# 17 — Future Control Surface (post-M7) > **Status: research / backlog — not scheduled.** M0–M7 cover the chat surface > (messages, streaming, tools, media, push, channels, search). This doc records > what the app could *additionally* control through the gateway, based on a > survey of the hermes-agent source (2026-08-21). Nothing here is locked; it is > a menu of options, each with the hermes backend that already implements it. ## The key insight Hermes already ships a **complete REST API** — `hermes_cli/web_server.py` plus `hermes_cli/web_routers/` — which is the backend of the desktop/dashboard UI. Our gateway plugin runs **inside the same `hermes gateway` process**, so every capability below is reachable by importing and calling the same functions the web server calls. Exposing one from the app = a new request/response frame pair in our protocol (`protocol.py` → `Protocol.kt` → `frames.schema.json`, the usual three-way mirror). The constraint is never "can hermes do it?" (it can — all of it) — it is how many frame pairs we want to add and the security review each one needs. ## Implementation paths 1. **Direct function calls (preferred).** The plugin imports the hermes modules (`cron.jobs`, `hermes_cli.kanban_db`, config loaders, …) and calls them. No extra process, no extra port, zero new deps. 2. **Proxy to the web server's REST API.** Only works if `hermes web` / `hermes dashboard` is running — it is not by default. Rejected for v1. ## Capability menu ### Cron jobs — fully controllable | App action | Hermes backend | |---|---| | List jobs (incl. disabled) | `cron/jobs.py` `list_jobs()` | | Create job | `cron/jobs.py` `create_job()` (schedules: `30m`, `every monday 9am`, 5-field cron, ISO one-shot) | | Edit job | `cron/jobs.py` `update_job(job_id, updates)` | | Pause / resume | `cron/jobs.py` `pause_job()` / `resume_job()` | | Trigger now | `cron/jobs.py` `trigger_job()` | | Delete job | web router `web_routers/cron.py` `DELETE /api/cron/jobs/{id}` | | Run history | `web_routers/cron.py` `GET /api/cron/jobs/{id}/runs`; `hermes_state_portability.py` `list_cron_job_runs()` | | Delivery targets | `web_routers/cron.py` `GET /api/cron/delivery-targets` | | One-tap suggestions | `cron/suggestions.py` — ready-to-run job specs the user accepts/dismisses; `accept_suggestion()` calls `create_job` directly. **Designed for a UI; ideal first feature.** | | Blueprints | `cron/blueprint_catalog.py`, `web_routers/cron.py` `GET /api/cron/blueprints` + `POST /api/cron/blueprints/instantiate` | Per-job fields worth surfacing: `model`/`provider` overrides, `skills`, `script`, `context_from` (chain job A's output into job B), `workdir`, multi-platform delivery. ### Kanban board — fully controllable | App action | Hermes backend | |---|---| | Boards: list / create / rename / delete / switch | `hermes_cli/kanban_db.py` `create_board()` / `list_boards()`; REST `plugins/kanban/dashboard/plugin_api.py` `/boards*` | | Tasks: create / list / show / update / delete | `kanban_db.py` `create_task()` / `list_tasks()` / `complete_task()`; REST `/tasks*` | | Comments / links / attachments | REST `/tasks/{id}/comments`, `/links`, `/tasks/{id}/attachments` | | Bulk operations | REST `POST /tasks/bulk` | | Dispatch / reassign / reclaim / estimate | REST `/dispatch`, `/tasks/{id}/reassign`, `/tasks/{id}/reclaim`, `/estimate` | | Runs: inspect / terminate | REST `/runs/{run_id}`, `/runs/{run_id}/terminate` | | Stats / diagnostics / active workers | REST `/stats`, `/diagnostics`, `/workers/active` | | Per-task model options | REST `/model-options` | Bonus: the kanban dispatcher already runs **inside the gateway** by default (`kanban.dispatch_in_gateway: true`), so a phone app would see dispatch activity live. The full REST surface (~30 endpoints) is in `plugins/kanban/dashboard/plugin_api.py`. ### Model / provider registry — fully controllable | App action | Hermes backend | |---|---| | Set active model | `web_server.py` `POST /api/model/set` | | List model options / info / recommended default | `GET /api/model/options`, `/api/model/info`, `/api/model/recommended-default` | | Auxiliary (side-LLM) models | `GET/PUT /api/model/auxiliary` | | MoA config | `GET/PUT /api/model/moa` | | Per-profile model | `web_routers/profiles.py` `PUT /api/profiles/{name}/model` | | Per-toolset model / provider / env | `web_routers/tools.py` `PUT /api/tools/toolsets/{name}/model` / `/provider` / `/env` | | Custom endpoints: CRUD + validate + activate | `web_server.py` `/api/providers/custom-endpoints*` | | Provider validation / OAuth flows | `POST /api/providers/validate`, `/api/providers/oauth*` | | API keys (`.env`): set / reveal / delete | `web_server.py` `GET/PUT/DELETE /api/env`, `POST /api/env/reveal` | | `config.yaml`: read / write / schema | `GET/PUT /api/config`, `GET /api/config/schema` | ### Webhooks | App action | Hermes backend | |---|---| | Subscribe / list / remove / test inbound webhook routes | `hermes_cli/webhook.py` (`hermes webhook` CLI: `_cmd_subscribe`, `_cmd_list`, `_cmd_remove`, `_cmd_test`); subscriptions stored in `~/.hermes/webhooks/subscriptions.json` | ### Sessions List, FTS search, rename, delete, bulk-delete, export (md/html), prune — `web_routers/sessions.py` (`/api/sessions*`). Overlaps with what the app already shows from its own chat; useful for browsing *other* platforms' sessions (Telegram, CLI, cron runs). ### Profiles CRUD, switch active profile, edit soul/description, per-profile model, export/import — `web_routers/profiles.py` (`/api/profiles*`). ### Skills List, toggle, create/edit content, hub search/install/uninstall/update — `web_routers/skills.py` (`/api/skills*`, `/api/skills/hub/*`). ### Tools / toolsets Enable/disable per platform, per-toolset config/model/provider/env — `web_routers/tools.py` (`/api/tools/toolsets*`). ### MCP servers CRUD, test, auth/OAuth flows, catalog browse + install — `web_routers/mcp.py` (`/api/mcp/*`). ### Git Status, branches, worktrees, and a full review flow (stage/unstage/revert/ commit/push/create-PR) — `web_routers/git.py` (`/api/git/*`). ### Files Upload/download/read/write, fs list/mkdir — `web_server.py` `/api/files*`, `/api/fs/*`. (Complements the existing media frames in `07-media.md`.) ### Messaging platforms List/configure/test other platforms (Telegram, WhatsApp onboarding) — `web_server.py` `/api/messaging/*`. ### Memory providers Config + setup per provider — `web_server.py` `/api/memory/providers/*`. ### Ops / system | App action | Hermes backend | |---|---| | Gateway restart / drain | `web_server.py` `POST /api/gateway/restart`, `/api/gateway/drain` | | Hermes update check / install | `POST /api/hermes/update`, `GET /api/hermes/update/check` | | Curator (skill maintenance) status / pause / run | `GET /api/curator`, `PUT /api/curator/paused`, `POST /api/curator/run` | | Audio: transcribe / TTS / voices | `POST /api/audio/transcribe`, `POST /api/audio/speak`, `GET /api/audio/elevenlabs/voices` | | System stats / status / health | `GET /api/system/stats`, `/api/status`, `/api/health` | | Learning graph node CRUD | `GET/PUT/DELETE /api/learning/node*` | ## Design notes 1. **Protocol cost is low.** The existing frame model (`type` + payload, request/response correlated by `id`) already fits; we would add pairs like `cron.list`/`cron.create`, `kanban.task.create`, `model.set`, following the standard three-way mirror (`gateway-plugin/protocol.py` → `app/shared/.../protocol/Protocol.kt` → `docs/protocol/frames.schema.json`). 2. **Security is the real gate.** The single-user model in `09-pairing-security.md` still holds, but control frames widen the blast radius of a leaked `IRIS_TOKEN`. Sensitive operations (env/secrets, config writes, gateway restart, profile deletion) should get either an in-app confirmation step or a capability flag negotiated at pairing. 3. **Read-heavy first.** Most of the value is in list/view frames (cheap, low-risk); write frames can follow per domain. 4. **Broadcast routing applies.** Frames broadcast to all connected devices (locked decision, `16-open-questions.md`); a control *response* should be routed to the requesting device only, like other request/response pairs. ## Natural first picks (suggested order) 1. **Cron** — list / create / pause / trigger + one-tap suggestions (the suggestion flow was literally designed for a UI). 2. **Kanban** — view board, add task, complete task. 3. **Model switch** — `model.set` + `model.options` (small, high value). 4. **Sessions** — list/search across platforms. All four are read-heavy with cheap writes and low security risk.