# Tools and scopes Devii's capabilities are a declarative **catalog** of actions. Each action declares a `handler` that routes it and an auth scope. The catalog is the single source of truth: the same definitions become the model's tool schema, the dispatch routing, and this reference. See also [Devii internals](/docs/devii-internals.html) and [Data and persistence](/docs/devii-data.html). Devii is a full agentic operator: it can run an entire user account, read and write a project's virtual filesystem line by line, drive the user's own browser, call any external HTTP/JSON API, manage Docker containers, learn lessons across sessions, schedule autonomous work, and let users mint their own tools in natural language. As of this build the catalog exposes **255 actions** across twenty-two handlers. The per-handler tables below cover the primary tools of each handler and are not an exhaustive enumeration of every action. ## How tools are declared `actions/spec.py` defines `Action` (name, method, path, params, `requires_auth`, `requires_admin`, `requires_primary_admin`, `handler`) and `Catalog`. `registry.py` unions the per-category tuples into `CATALOG`. `tool_schema()` projects each action into the JSON tool schema sent to the model; `tool_schemas_for(authenticated, is_admin, is_primary_admin)` is the **scope filter**: guests only receive actions where `requires_auth` is false, `requires_admin` actions are offered only to administrators, and `requires_primary_admin` actions (the read-only database API tools) are offered only to the **primary administrator** (the oldest Admin account), so account-operating, admin-only, and primary-admin-only tools are never presented to a guest, member, or junior admin. **Scope legend** used throughout this page: **public** = offered to everyone including guests; **auth** = signed-in members (and the account-operating actions run as that user); **admin** = administrators only, gated twice (schema withheld and dispatcher refusal); **primary admin** = the oldest Admin account only (the database API tools), gated the same way. ## Handler categories (scopes) | Handler | Scope | What it does | |---|---|---| | `http` | platform API | The bulk of the catalog (`actions/catalog.py`): posts, comments, votes, follows, messages, projects and their virtual filesystem, gists, bookmarks, polls, notifications, news, uploads, and admin endpoints. Sent over the `PlatformClient` with the user's auth. | | `login` / `logout` / `status` | session | Authenticate or report auth state. | | `fetch` | web | `fetch_url` reads a web page; `http_request` makes any-method HTTP calls to external APIs. Both carry an SSRF guard and size caps. | | `rsearch` | external web | `rsearch` (web/image search), `rsearch_answer` (web-grounded AI answer), `rsearch_chat` (direct AI chat), `rsearch_describe_image` (vision). They call an external public service, not this platform, gated by `devii_rsearch_enabled` (URL via `devii_rsearch_url`). | | `docs` | knowledge | `search_docs` over this documentation. | | `agentic` | reasoning | `plan`, `reflect`, `recall`, `forget_lessons`, `verify`, `delegate`, `eval`. | | `task` | scheduling | Create/list/update/delete/run autonomous tasks (once / interval / cron). | | `cost` | accounting | `usage_quota` reports the owner's 24h quota usage as a percentage (no money, available to everyone); `cost_stats` and `ai_usage` report full USD detail and are admin-only. | | `chunks` | large results | `read_more` paginates any oversized tool result. | | `customization` | look and behaviour | The `customize_*` tools persist per-owner CSS and JavaScript scoped to a page type or the whole site. | | `virtual_tool` | user-defined tools | The `tool_*` tools let a user invent new Devii tools in natural language; each stored tool re-runs Devii on its prompt. | | `avatar` | on-screen | The `avatar_*` tools (md-clippy character) - web only. | | `client` | the browser | `get_page_context`, `run_js`, navigation, highlights, toasts, and `open_terminal` - run in the user's own browser; `run_js` is gated by `devii_allow_eval`. | | `container` | Docker (admin) | The `container_*` tools manage supervised container instances on the shared `ppy` image - admin only. | | `email` | external mailbox | The `email_*` tools connect to the user's OWN external mailbox over IMAP/SMTP (Python stdlib, run off-thread), not this platform. Signed-in users only; gated by `devii_email_enabled`. Per-owner credentials live in `email_accounts` and the mail host is SSRF-guarded. | | `behavior` | self-configuration | `update_behavior` persists the owner's `# TRUTH RULES AND BEHAVIOR` system-prompt section (signed-in owner-scoped, self-prompted). | | `notification` | preferences | `notification_list` / `notification_set` / `notification_reset` read and write the owner's per-type per-channel notification preferences. | | `ai_correction` | content correction | `ai_correction_get` / `ai_correction_set` read and write the owner's AI content-correction settings. | | `ai_modifier` | content modifier | `ai_modifier_get` / `ai_modifier_set` read and write the owner's `@ai` modifier settings. | | `interaction` | interactive widgets | `ui_prompt` / `ui_cancel` / `ui_notify` present channel-aware asks; `interactions_get` / `interactions_set` read and write the owner's preference (admin default on the Devii service; users may override or reset to inherit). | | `telegram` | Telegram | `telegram_send` pushes a message to the owner's paired Telegram from a turn or scheduled task. | ## Complete action reference The primary tools of the catalog, grouped by handler (this is a representative reference, not an exhaustive list of all 255 actions). Mutating platform calls and irreversible actions (deletes, visibility/read-only flips, destructive container commands) additionally pass through the dispatcher's confirmation gate before they run. Every content delete (`delete_post`, `delete_comment`, `delete_gist`, `delete_project`, `project_delete_file`, `delete_media`, `delete_attachment`, `admin_delete_news`) is **confirmed** by the dispatcher: the first call is refused with a message to confirm with the user, and only a repeat call carrying `confirm=true` runs. Each is a **soft delete**, restorable from the admin trash. These tools carry `requires_auth` (not `requires_admin`) because a member may delete their **own** content through them. The platform API enforces the rest: an **administrator** operating Devii may delete **any** member's post, comment, gist, project, project file, or attachment, while a member is refused (owner-or-admin is checked on the endpoint, not in the agent). ### Session and account (`status`, `login`, `logout`, `http`) | Tool | Scope | What it does | |---|---|---| | `auth_status` | public | Report whether the current session is authenticated. | | `login` | public | Authenticate with email and password and start a session. | | `logout` | auth | End the current session. | | `signup` | public | Create a new account. | | `forgot_password` | public | Request a password reset email. | | `reset_password` | public | Reset a password using a reset token. | | `view_profile` | public | View a user profile. | | `search_users` | auth | Search for users by name. | | `update_profile` | auth | Update the current user's profile. | | `regenerate_api_key` | auth | Issue a new API key and invalidate the current one. | | `follow_user` | auth | Follow a user. | | `unfollow_user` | auth | Unfollow a user. | | `list_followers` | public | List the users who follow a profile. | | `list_following` | public | List the users a profile follows. | ### Posts, comments, and engagement (`http`) | Tool | Scope | What it does | |---|---|---| | `view_feed` | auth | View the activity feed. | | `create_post` | auth | Create a new post (optionally with a poll). | | `view_post` | auth | View a single post by slug. | | `edit_post` | auth | Edit an existing post. | | `delete_post` | auth | Delete a post: own post, or any post when admin (soft delete, confirmation required). | | `create_comment` | auth | Create a comment on a post or other target. | | `delete_comment` | auth | Delete a comment: own comment, or any comment when admin (soft delete, confirmation required). | | `vote` | auth | Cast or toggle a vote on a target. | | `react` | auth | Toggle an emoji reaction on a target. | | `vote_poll` | auth | Vote in a poll. | | `list_bookmarks` | auth | List saved bookmarks. | | `toggle_bookmark` | auth | Toggle a bookmark on a target. | | `view_leaderboard` | auth | View the leaderboard. | ### Projects and the virtual filesystem (`http`) | Tool | Scope | What it does | |---|---|---| | `list_projects` | auth | List projects. | | `view_project` | auth | View a project by slug. | | `create_project` | auth | Create a new project. | | `edit_project` | auth | Edit an existing project. | | `delete_project` | auth | Delete a project: own project, or any project when admin (soft delete, confirmation required). | | `project_set_private` | auth | Mark a project private or public (confirmation required). | | `project_set_readonly` | auth | Mark a project read-only or writable (confirmation required). | | `project_list_files` | public | List every file and directory in a project filesystem. | | `project_read_file` | public | Read one file from a project filesystem. | | `project_write_file` | auth | Create or overwrite a whole text file. | | `project_read_lines` | public | Read a 1-indexed line range of a text file. | | `project_replace_lines` | auth | Replace an inclusive 1-indexed line range. | | `project_insert_lines` | auth | Insert content before a 1-indexed line. | | `project_delete_lines` | auth | Delete an inclusive 1-indexed line range. | | `project_append_file` | auth | Append content to the end of a text file. | | `project_upload_file` | auth | Upload a local file into a project directory. | | `project_make_dir` | auth | Create a directory (and parents). | | `project_move_file` | auth | Move or rename a file or directory. | | `project_delete_file` | auth | Delete a file or directory recursively: project owner, or any project when admin (soft delete, confirmation required). | | `zip_project` | public | Build a downloadable zip archive of a whole project. | | `zip_status` | public | Check a zip job and obtain its download link once finished. | | `fork_project` | auth | Fork a project into a new project owned by the current user. | | `fork_status` | public | Check a fork job and obtain the new project once finished. | ### Tools (`http`) | Tool | Scope | What it does | |---|---|---| | `seo_diagnostics` | public | Queue an SEO audit of a URL or sitemap and obtain its job uid and status URL. | | `seo_status` | public | Check an SEO audit and obtain its score, grade, and report link once finished. | | `seo_report` | public | Read a finished SEO audit report: overall score and grade, per-category scores, per-check results, per-page details, and site-wide checks. | ### Messages and notifications (`http`) | Tool | Scope | What it does | |---|---|---| | `list_messages` | auth | View direct message conversations. | | `search_message_users` | auth | Search users to message. | | `send_message` | auth | Send a direct message. | | `list_notifications` | auth | List notifications. | | `notification_counts` | auth | Get unread notification and message counts. | | `open_notification` | auth | Open a notification and follow it. | | `mark_notification_read` | auth | Mark a single notification read. | | `mark_all_notifications_read` | auth | Mark all notifications read. | ### Gists, issues, news, and uploads (`http`) | Tool | Scope | What it does | |---|---|---| | `list_gists` | auth | List gists. | | `view_gist` | auth | View a gist by slug. | | `create_gist` | auth | Create a gist. | | `edit_gist` | auth | Edit a gist. | | `delete_gist` | auth | Delete a gist: own gist, or any gist when admin (soft delete, confirmation required). | | `list_issues` | auth | List reported issues. | | `create_issue` | auth | Report an issue. | | `list_news` | auth | List news articles. | | `view_news` | auth | View a news article by slug. | | `upload_file` | auth | Upload a local file and obtain its attachment uid. | | `attach_url` | auth | Download a public URL on the server and store it as an attachment, returning its uid to pass in `attachment_uids`. | | `delete_attachment` | auth | Delete an uploaded attachment: own attachment, or any when admin (soft delete, confirmation required). | ### Administration (`http`) | Tool | Scope | What it does | |---|---|---| | `admin_overview` | admin | View the admin overview. | | `site_analytics` | admin | Site-wide aggregate analytics in one call. | | `ai_usage` | admin | AI gateway usage, cost, latency, and reliability metrics. | | `admin_list_users` | admin | List users for administration. | | `admin_set_user_role` | admin | Set a user's role. | | `admin_set_user_password` | admin | Set a user's password. | | `admin_toggle_user` | admin | Toggle a user's active state. | | `admin_get_settings` | admin | View site settings. | | `admin_save_settings` | admin | Save site settings. | | `admin_list_news` | admin | List news for administration. | | `admin_toggle_news` | admin | Toggle a news article. | | `admin_publish_news` | admin | Publish a news article. | | `admin_landing_news` | admin | Set a news article as landing content. | | `admin_delete_news` | admin | Delete a news article (soft delete, confirmation required). | | `admin_list_services` | admin | View managed services. | | `admin_services_data` | admin | Live status, metrics, and log tail for every service. | | `admin_service_status` | admin | Live status, metrics, and log tail for one service. | | `admin_start_service` | admin | Start a managed service. | | `admin_stop_service` | admin | Stop a managed service. | | `admin_run_service` | admin | Run a managed service once. | | `admin_clear_service_logs` | admin | Clear a managed service's logs. | | `admin_config_service` | admin | Update a managed service's configuration. | The `admin_*` tools carry `requires_admin=True`, so they are gated twice: their schema is withheld from non-administrators and the dispatcher independently refuses them for a non-admin owner (the platform endpoints also return 403 to non-admins as a third layer). The financial `cost_stats` is admin-only in the same way. Beyond the tools above the catalog also exposes further admin-only `http` actions - audit-log (`audit_log`, `audit_event`), backups (`backups_overview`, `backup_run`, `backup_status`, `backup_delete`, `backup_schedule_create`, `backup_schedule_delete`), AI gateway routing (`gateway_providers`, `gateway_models`, `gateway_provider_set`, `gateway_provider_delete`, `gateway_model_set`, `gateway_model_delete`), AI-quota resets, media restore/purge, and the primary-administrator-only read-only database tools (`db_list_tables`, `db_table_schema`, `db_list_rows`, `db_get_row`, `db_query`, `db_design_query`). ### Web and external APIs (`fetch`, `rsearch`) | Tool | Scope | What it does | |---|---|---| | `fetch_url` | public | Fetch a web page and return its readable text content. | | `http_request` | auth | Make an arbitrary HTTP request (GET/POST/PUT/PATCH/DELETE/HEAD/OPTIONS) to any external API, with custom headers and a JSON, form, or raw body, returning the full response. | | `rsearch` | public | Search the public web and images via the external rsearch aggregator. | | `rsearch_answer` | public | Get an AI answer to a question, grounded in fresh web search. | | `rsearch_chat` | public | Send a prompt to the external rsearch AI for a direct answer. | | `rsearch_describe_image` | public | Describe a public image URL using the external vision model. | `http_request` is the general HTTP client for external REST/JSON APIs. It sends any method with a `json`, `form`, or raw `body`, sets the JSON Content-Type automatically, and returns the response status, headers, and content (non-2xx is returned, not raised, so API errors are readable). It must be called as a first-class tool: a user-defined tool cannot perform network I/O itself, so wrapping the call in a self-invoking tool would recurse and hit the self-evaluation depth limit. Both `fetch` tools refuse private and loopback addresses (SSRF guard, overridable with `DEVII_FETCH_ALLOW_PRIVATE`) and cap the response size. ### Reasoning and memory (`agentic`) | Tool | Scope | What it does | |---|---|---| | `plan` | public | Record the structured execution plan for the request (required first call). | | `reflect` | public | Record a reflection and persist it as a reusable lesson. | | `recall` | public | Retrieve relevant lessons learned from past requests. | | `forget_lessons` | public | Permanently delete learned lessons from private memory. | | `verify` | public | Confirm a change took effect, satisfying the verification gate. | | `delegate` | public | Spawn a focused sub-agent for a self-contained sub-task. | | `eval` | public | Run a prompt through a fresh Devii sub-agent and return its result. | `delegate` and `eval` run a nested `react_loop` under a contextvar depth guard (`MAX_EVAL_DEPTH`), so self-evaluation cannot recurse without bound. ### Autonomous tasks (`task`) | Tool | Scope | What it does | |---|---|---| | `create_task` | public | Queue a prompt to run autonomously on a schedule with full tool access. | | `list_tasks` | public | List queued tasks and their schedules and last results. | | `get_task` | public | Get a single task including its full last result. | | `update_task` | public | Update a task's prompt, label, enabled state, or schedule. | | `delete_task` | public | Delete a queued task. | | `run_task_now` | public | Trigger a task to execute immediately on the next scheduler tick. | These tools are `public` (no sign-in required), but persistence differs by owner. A **signed-in user's** tasks are stored in `devii_tasks` and are run by the lock-owner `DeviiService` itself, so a queued reminder survives a server restart and fires even with no terminal open. A **guest's** tasks live in an in-memory store and run only while the session stays connected. `create_task` and `update_task` take a `notify` flag: when a task with `notify=true` fires, the owner is sent a `reminder` in-app notification and a live toast carrying the result, so reminders reach a signed-in user even when Devii is closed (guests get no notification). Times in task records are UTC; the agent's system prompt carries a `# CURRENT TIME` block with the current UTC time plus the user's local time and timezone (captured from the browser, persisted to `users.timezone`), so wall-clock requests convert to a correct `run_at` while relative requests use `delay_seconds`. ### Accounting and large results (`cost`, `chunks`) | Tool | Scope | What it does | |---|---|---| | `usage_quota` | public | Report the current user's AI usage as a percentage of their 24h quota. | | `cost_stats` | admin | Report token usage and full USD cost statistics for the session. | | `read_more` | public | Read the next part of a previously truncated tool result. | ### Email (`email`) The `email_*` tools reach the user's OWN external mailbox over IMAP/SMTP, not this platform, and are available to signed-in users only (never guests). An account must be configured with `email_account_set` under a label first; every other tool takes that label as its `account`. Credentials are stored per owner in `email_accounts` and the password is never returned. The mail host is checked against the SSRF guard before each connect. `email_send` is a real outbound action, and `email_delete_message` and `email_account_delete` are confirmation-gated. | Tool | Scope | What it does | |---|---|---| | `email_accounts_list` | auth | List the user's configured email accounts (passwords masked). | | `email_account_get` | auth | Read one account's connection settings (password masked). | | `email_account_set` | auth | Create or update an IMAP/SMTP account connection (sensible defaults applied). | | `email_account_delete` | auth | Delete a saved account connection (confirmation required). | | `email_list_folders` | auth | List the mailbox folders on the account. | | `email_list_messages` | auth | List messages in a folder, newest first, with optional filters and paging. | | `email_search` | auth | Search a folder by sender, subject, date, text, or read/flag state. | | `email_read_message` | auth | Read a message's full body, headers, and attachment list. | | `email_mark` | auth | Mark a message read, unread, flagged, or unflagged. | | `email_set_flags` | auth | Add or remove arbitrary IMAP flags on a message. | | `email_move_message` | auth | Move a message to another folder. | | `email_delete_message` | auth | Delete a message, optionally to a Trash folder (confirmation required). | | `email_send` | auth | Send an email via the account's SMTP server. | ### Customization (`customization`) | Tool | Scope | What it does | |---|---|---| | `customize_list` | public | List the user's saved CSS/JS customizations. | | `customize_get` | public | Read the full saved CSS or JS code for one scope. | | `customize_set_css` | public | Permanently save custom CSS for a page type or the whole site (confirmation required). | | `customize_set_js` | public | Permanently save custom JavaScript for a page type or the whole site (confirmation required). | | `customize_reset` | public | Delete saved customizations, restoring the defaults (confirmation required). | | `customize_set_enabled` | auth | Show or suppress customizations without deleting them. | ### User-defined tools (`virtual_tool`) | Tool | Scope | What it does | |---|---|---| | `tool_create` | public | Create a new user-defined tool that runs a stored prompt when called. | | `tool_list` | public | List the user's defined tools with their descriptions and status. | | `tool_get` | public | Read a user-defined tool's full prompt and settings. | | `tool_update` | public | Update a user-defined tool's description, prompt, input hint, or enabled state. | | `tool_delete` | public | Delete a user-defined tool. | A user-defined tool is a stored prompt that re-runs Devii; the actual work is still performed by the built-in tools the prompt tells Devii to call (for example `http_request` for an API or the `project_*` tools for files). It cannot do network or file I/O on its own and must not be designed to keep calling itself. ### On-screen avatar (`avatar`, web only) | Tool | Scope | What it does | |---|---|---| | `avatar_show` | public | Show devii (the character) on screen. | | `avatar_hide` | public | Hide devii with a goodbye animation. | | `avatar_speak` | public | Show a line of text in devii's speech balloon. | | `avatar_list_animations` | public | List every animation the current character supports. | | `avatar_play_animation` | public | Play a specific named animation. | | `avatar_random_animation` | public | Play a random non-idle animation to react expressively. | | `avatar_move_to` | public | Walk devii to a pixel position on screen. | | `avatar_gesture_at` | public | Make devii gesture toward a pixel position. | | `avatar_get_viewport` | public | Get the screen size and devii's current position. | | `avatar_stop` | public | Stop all queued animations and speech immediately. | | `avatar_list_characters` | public | List every character devii can appear as. | | `avatar_switch_character` | public | Change which character devii is rendered as. | ### Browser control (`client`, web only) | Tool | Scope | What it does | |---|---|---| | `get_page_context` | public | Read the user's current page: URL, title, viewport, scroll, selection, headings, auth state, and page type. | | `run_js` | public | Execute JavaScript in the user's browser and return its result (gated by `devii_allow_eval`). | | `highlight_element` | public | Highlight an element with an outline and optional callout, for live tutorials. | | `clear_highlights` | public | Remove all highlights and callouts. | | `show_toast` | public | Show a brief on-screen message. | | `scroll_to_element` | public | Smoothly scroll an element into view. | | `navigate_to` | public | Send the user's browser to a URL. | | `reload_page` | public | Refresh the user's current page. | | `open_terminal` | admin | Open a floating interactive terminal attached to a running container instance. | ### Containers (`container`, admin only) | Tool | Scope | What it does | |---|---|---| | `container_list_instances` | admin | List a project's container instances and their status. | | `container_create_instance` | admin | Create and start an instance on the shared `ppy` image with the project files at `/app`. | | `container_configure_instance` | admin | Edit an instance's run-as user, boot language/script/command, restart policy, and limits. | | `container_instance_action` | admin | Control an instance: start, stop, restart, pause, resume, delete, or sync (delete is confirmed). | | `container_logs` | admin | Read the recent logs of a running instance. | | `container_exec` | admin | Run a one-shot command inside a running instance (destructive commands are confirmed). | | `container_stats` | admin | Get aggregated resource and runtime statistics for an instance. | | `container_schedule` | admin | Schedule a start or stop (cron, interval, or one-time). | ## Auth scope `requires_auth` defaults to true. The dispatcher refuses an auth-required action when the platform client is not authenticated. `requires_admin` actions are gated twice: the model never receives their schema unless the session owner is an administrator, and the dispatcher independently rejects any `requires_admin` action for a non-admin owner. The owner's admin status is resolved server-side from the session/API-key user role (`is_admin(user)`), never from client input. **Role** enforcement for platform data is also done by the platform endpoints themselves (for example the admin endpoints return 403 to non-admins). The local handlers (`avatar`, `client`, `agentic`, `task`, `docs`, `cost`, `chunks`, `customization`, `virtual_tool`) act only on the owner's own session, browser, or memory; financial cost figures are never disclosed to non-admins. ## The ReAct protocol The system prompt enforces an operating protocol: `plan()` must be the first tool call; authentication and permissions gate account actions; `recall()` consults lessons; mutating actions require a `verify()`; tool errors trigger a `reflect()`. For counts and "how many" questions the model uses `site_analytics` (the admin-only [analytics endpoint](/docs/admin.html)) rather than paging lists, and `search_docs` before guessing a route. To call an external API it uses `http_request` directly. The external `rsearch_*` web tools are not platform-specific: the prompt makes Devii prefer platform tools and call `rsearch_*` only when the user explicitly asks to search the web or an outside source. See [Security and limits](/docs/devii-security.html) for the confidentiality and memory rules. ## Browser control (handler `client`) The `client` handler runs tools in the user's own browser through the web terminal (`DeviiClient.js`), routed by `session._browser_request` to the most visible tab with a 60 second deadline. Beyond the guidance tools (`get_page_context`, `navigate_to`, `reload_page`, `highlight_element`, `show_toast`, `scroll_to_element`, `clear_highlights`) and the raw escape hatch `run_js`, Devii drives the page with a structured automation set built on discovery and stable element refs: - **Discover:** `discover_elements` lists the actionable elements in reading order, each with a stable ref (e3), role, accessible label, robust selector, and live state; `read_element` inspects one. - **Act:** `click_element`, `fill_field` (fires real input/change events, handles CodeMirror and contenteditable), `set_control` (checkboxes/radios/selects), `submit_form` (fill then submit a whole form), `press_key`. Every act tool returns a delta (URL change, modal open/close, new toast, validation error, element gone) so Devii confirms the result. - **Sequence and wait:** `wait_for` polls until an element is visible/hidden/contains text so steps do not race; `run_sequence` runs an ordered list of steps in one round-trip, stopping at the first failure. The agent is steered (the DRIVING THE BROWSER prompt section) to follow context -> discover -> act on refs -> wait -> verify, preferring these over `run_js`. Two independent admin gates apply: `run_js` is gated by `devii_allow_eval`, and the mutating control tools (click, fill, set, submit, press_key, run_sequence) by `devii_browser_control`; the read-only tools (context, discover, read, wait) are always available. These tools act only on the user's own screen, and platform routes still enforce their own confirmations (a clicked Delete still opens the confirm dialog), so they add no new path to data loss.