Omniscio documentation
Browse all documentation
  1. Getting Started13
  2. Sessions & Agents115
  3. Inbox & Notifications59
  4. Projects & Tasks95
  5. Automation & Scheduling75
  6. Knowledge & Memory26
  7. AI Features60
  8. Integrations100
  9. Plugins & Marketplace33
  10. Cloud & Teams56
  11. Settings & Customization58
  12. Account & Billing28
  13. Troubleshooting84
  14. CLI & API Reference22
  15. Legal & Policies4
  16. Uncategorised22

Omniscio Control (how an AI agent changes the app live)

A bundled skill that teaches an AI agent how to read and change a running Omniscio install through the app's own control server — settings, sessions, scheduled work, the inbox — instead of editing files on disk. Agent-facing: you just ask in plain English, and the skill carries the rules, the approval model and the error handling.

What it is

What it is

Omniscio Control is a bundled Claude Code skill that teaches any AI agent — Claude Code, ChatGPT with file access, the in-app chat panel, an external Claude session you spawn yourself — how to read and change a running Omniscio install without editing files on disk or restarting the app.

It is installed into ~/.claude/skills/omniscio-control/ automatically on every Omniscio launch (no opt-in, no setup). Any Claude Code session you spawn — from Omniscio or from any other repo — sees the skill in its toolbelt and reaches for it when the user asks Omniscio-related questions.

The problem it solves

Before this skill existed, when a user asked an AI to "turn off Focus Mode" or "create a cron job to run every weeknight at 9 PM", the AI would do one of three things, all wrong:

  1. Write to config.json on disk — Omniscio's main process holds settings in memory; a disk edit changes nothing until restart, and then Omniscio's safeStorage re-encryption can clobber the change on the next save.
  2. Try to spawn a fresh Omniscio and shove flags in — Omniscio's single-instance lock blocks the second process; the request silently fails.
  3. Tell the user "I can't do that — change it manually in Settings" — the user has to walk a non-programmer through the UI.

Omniscio has had a localhost HTTP control server on 127.0.0.1:19519 for over a year (bearer-token-auth, JSON-in / JSON-out, hundreds of routes across dozens of surface areas — enumerated in the lint-checked endpoint-index.md). The AI just didn't know it existed, and even once it did, it had a hard time discovering which of the many routes served a given request. Omniscio Control is the missing manual — and, as of the 2026-05-29 redesign, a manual built so the agent can always find the piece it needs and never has to say "there's no tool for that."

The discoverability redesign (2026-05-29)

The earlier skill had a hub plus ~10 surface files, and its routing table only named about half the surfaces the server actually exposed. An agent asking "how do I manage a Drip?" or "is there a heap-snapshot endpoint?" would dead-end, because those surfaces had no doc and the hub didn't mention them. The redesign closes that hole with a rigid three-layer architecture and two CI lints that keep it honest:

  • 100% route coverage. Every one of the server's routes — including power, diagnostic, feature-flagged, and kill-switch-gated ones — now has a documented home.
  • A master fallback. endpoint-index.md lists the routes in one searchable table, so even when the hub's intent router doesn't obviously name a surface, the agent has a last-resort lookup that is machine-checked against the served route set — every route is either documented as a row or named on the inherited-debt list, so a route missing from the table is not proof the server lacks it.
  • It can't silently drift. Two lint tests fail the build the moment the docs and the server disagree (see "Self-maintaining" below).

The category discovery layer (2026-06-23)

The 2026-05-29 redesign fixed navigation — once the agent opens the skill, it can always find the right surface. But triggering stayed weak: all its surfaces sat behind one umbrella description, so on an implicit ask ("remind me at 3pm", "what is my other session doing") the model often never connected the request to Omniscio at all — it answered in chat or reached for a generic skill. One description is a single trigger surface competing against ~80 other skills.

The fix adds a thin discovery layer on top of the hub — seven sibling "category" skills, each a short overview with its own sharp, phrasing-rich description (the real trigger surface) that routes straight to the hub's spokes:

  • omniscio-sessions — sessions, projects, tags, cross-session messaging, spawn.
  • omniscio-scheduling — cron, alarms, drip ("remind me at 3pm", "every morning run X").
  • omniscio-automation — automations, recipes, away-mode, Nighty Tidy, OpenClaw port.
  • omniscio-content — tasks, mind maps, whiteboards, KMS notes, scratchpads, saved prompts, bookmarks, AI coaching.
  • omniscio-settings — settings, keybindings, app control, running apps, plugins, browser logins.
  • omniscio-inbox — alerts, the approval queue, quick replies, email-summarizer, SMS, intake sources, feedback.
  • omniscio-observe — status/search, UI pointing, diagnostics, share, convert, Google APIs, Team Time.

Each category skill is thin — it owns no endpoints; it names omniscio-control for the shared mechanics (auth, the approval model, errors) and links directly to the relevant ../omniscio-control/<spoke>.md docs. The spokes stay in one place (DRY). All eight skills install together as one bundle (cliSkillIds).

The same change rebalanced the Omniscio awareness preamble (AMC_AWARENESS_SYSTEM_PROMPT, injected into every Omniscio-spawned session): it now names the seven categories and drops the old "entirely optional … never just because the capability exists" tail that measurably discouraged invocation — restraint is now a light "judiciously, not on every turn." See amc-session-awareness.md.

Self-maintaining (a third lint). tests/unit/lint/amc-control-category-skills.test.ts derives the category set from the manifest's cliSkillIds and asserts every category skill has valid frontmatter, links only real surfaces (no dead links), and that the union of all category references covers every omniscio-control surface — so a new spoke can never be added without being routed into a category, and no surface can silently fall back behind the umbrella description.

Where to find it

There is no screen for it. The skill lives with your Claude Code skills and is loaded by an agent that needs to act on the app; what you see is the result of what you asked for in chat.

How it behaves

How to use it

The skill is agent-facing, not user-facing — most users never see it directly. The user just talks to their AI in plain English:

  • "Turn off the typing-indicator setting in Omniscio."
  • "Pause my Claude session called 'inbox triage' and snooze it until 9 AM tomorrow."
  • "Set up a Drip that releases one of these 30 articles into my inbox every morning."
  • "Subscribe this project to nightly Nighty Tidy audits, lint in report mode."
  • "Publish this markdown file as a share link."
  • "Have the research session tell the writing session what it found."
  • "Show me all the pending Omniscio approvals in my inbox and tell me what each one would do."

The AI loads the omniscio-control skill, reads the hub (SKILL.md), routes to the matching surface file via the "Pick your surface" table, and — if the intent isn't obvious — searches endpoint-index.md. Then it makes the HTTP call.

Spawning into the cloud

A cloud session is the same call with one more field. POST /project/:name/new {"prompt": "…", "location": "cloud"} — location takes "local" or "cloud", and omitting it is today's local spawn, byte for byte. You do not need /fanout for a single cloud session; /fanout is the bake-off road (one prompt across many projects) and it accepts the same location per target.

Two things that once sent an agent the wrong way (it concluded "the cloud feature is off and the spawn API can't express it", and spawned locally):

  • GET /cloud/preference → {"on": false} does NOT mean cloud sessions are off. That switch chooses where agent checks run — the test/build offload. Cloud sessions are a separate feature. The answer now carries a governs line saying exactly that, so the scope is readable from the payload rather than from documentation.
  • While cloud sessions are dark, location: "cloud" is inert — the session launches locally, exactly as it did before the feature existed. That is deliberate (contract purely-additive), not a silent failure. A refused cloud launch names its reason; read the refusal instead of concluding the feature is switched off.

Spawning into the cloud is still a billable spawn — the same explicit per-request authorization rule above applies.

What "live" means

  • Cosmetic / personal-preference changes apply immediately: keybindings, cosmetic project edits, project creation, sidebar reordering, per-session tag apply/unapply, quick replies, bookmarks, alarms, Team Time, the Tasks outliner, Drip item management, share publishing, feedback, UI highlight, app reload, and session lifecycle (pause / unpause / snooze / archive — benign + reversible; re-gate via Settings → CLI Control → Approval requirements). The Omniscio UI reflects the change within a renderer tick.
  • Anything that affects the inbox, billing, your data, or other agents lands in your Approvals inbox first: settings, cron jobs, automations, recipes (authoring + per-run), project deletion / docs / bug-intake, away-mode rules, the tag library, Drip + Drip-source CRUD, email-summarizer rules, AI-coaching artifact edits, and arming a bug-intake source. Each shows up as a card in Inbox → Approvals.
  • Some routes spawn real Claude processes (cost money) — /project/:name/new, /recipes/run, /recipe/configs/:id/run, /nighty-tidy-2/.../run-now, /ai-coaching/interviews, /agent/sessions. The skill tells every agent to call these only on explicit per-request user authorization, then verify the result.
  • Either way, you never restart Omniscio. The change is in memory and on disk at the same moment.

Auth — there is one bearer token, the AI fetches it itself

Every CLI control request (except a handful of health / open-read / UI-nav routes) needs Authorization: Bearer <token>. The token lives DPAPI-encrypted in the user's Windows vault as amc-cli and is auto-delivered to ~/.amc/cli-token (mode 0600) on every Omniscio launch. The skill tells every agent the same fetch order:

  1. DPAPI vault first — powershell.exe -NoProfile -File "$HOME/.claude/secrets/get-secret.ps1" amc-cli (the source of truth on this machine).
  2. Dotfile — ~/.amc/cli-token (a single UTF-8 line).
  3. Environment variable — $AMC_CLI_TOKEN.

The skill never echoes the token in chat, and tells the user to rotate via Omniscio → Settings → CLI Control → Regenerate if a token ever leaks. (After a rotation the dotfile updates but the vault does not — the skill documents the one-line vault re-set.)

Identify your session — X-AMC-Source-Session-Id

Alongside the bearer token, an Omniscio-spawned agent sends -H "X-AMC-Source-Session-Id: $AMC_SESSION_ID" (Omniscio injects AMC_SESSION_ID into every spawned agent's environment). This makes every action and spawn traceable back to the calling session — an inbox action reads "Generated by <your session>", and a session you spawn opens with a clickable "Spawned by" note. It is a trace hint, not a security boundary. For session spawns it is required by default: with the requireSpawnSourceSession setting on (the default), POST /project/:name/new and POST /agent/sessions refuse a spawn that carries no source with HTTP 400. A non-session caller (a manual script with no $AMC_SESSION_ID) either sends a real session id or has the user turn the setting off in Settings → CLI Control.

Rate limits

Shared across all endpoints, all surfaces:

  • 10 mutations per minute per token (returns 429).
  • 60 reads per minute per token hash.
  • 20 pending approval items in the inbox at any time (the queue cap — once full, every new approval-gated request returns 409).

A few surfaces have their own buckets (cross-session messaging 120/hour; agent-sessions 10 spawns/hour; UI snapshot 60/min), documented in their spoke files.

Trigger keywords

The skill's description field lists every common phrasing — change/toggle/set a setting; pause/snooze/archive/spawn/message a session; create/edit/run a cron job, automation, recipe, drip, audit, tag, project, bookmark, alarm, keybinding; manage quick replies, Team Time, email-summarizer rules, intake sources, AI coaching, shares, the Tasks outliner; file feedback; read status/search/state; point at the UI; diagnostics. If the user's request mentions Omniscio or maps onto any Omniscio capability, the skill loads, the hub routes, and endpoint-index.md backstops anything the router doesn't name.

Where it does not apply

The skill covers Omniscio's own state — its settings, data, inbox, scheduled work, and UI. It does not spawn arbitrary Claude sessions on its own initiative; the billable routes are called only with explicit per-request user authorization in the current chat, and even then the agent never echoes the bearer token. For the inbox approval flow the user sees, see cli-pending-actions.md.

For agents

How it works

Three-layer hub-and-spoke structure

~/.claude/skills/omniscio-control/
  SKILL.md            ← Hub. Golden rule, auth, approval model, rate limits,
                        idempotency, error table, and a "Pick your surface"
                        intent router covering ALL 42 surfaces.
  endpoint-index.md   ← Master fallback. One row per documented route (2,382
                        of 2,556 served, measured 2026-09-15): method, path,
                        surface doc, auth, gating, one-liner. Searchable. The
                        rest are named in tests/unit/lint/amc-control-doc-debt-
                        baseline.ts, so a route absent here may still be served.
  <42 surface docs>   ← One flat .md per surface (settings, cron, drip,
                        nighty-tidy, share, ai-coaching, diagnostics, …).
                        Each: "Read SKILL.md first" backlink + ## Endpoints
                        table + workflow + errors.

The 42 surfaces: read-and-status, sessions, sessions-spawn, agent-sessions, cross-session-messaging, projects, settings, settings-catalog, cron, automations, recipes, away-mode, keybindings, tags, quick-replies, alarms, team-time, bookmarks, tasks, tasks-v2, drip, alert, email-summarizer, nighty-tidy, intake-sources, ai-coaching, share, google-apis, feedback, ui-discovery, discover-values, app-control, merge-priority, diagnostics, pending-actions, kms, mindmaps, plugins, sms, scratchpads, openclaw-port, golden-paths.

The agent loads the hub first, follows one link to the right spoke, and falls back to endpoint-index.md only when the intent is ambiguous. Two hops, maximum, from cold start to the exact endpoint.

Folded-in legacy skills

The redesign folded three previously-standalone skills into omniscio-control so there is one place to look:

  • amc-cli-auth → its token-fetch + rotation + "dotfile missing despite CLI control on" troubleshooting now lives in the hub's Authentication section.
  • amc-ui-discovery → became ui-discovery.md (/ui/snapshot, /ui/highlight, /ui/highlight/clear).
  • amc-share-publish → became share.md (/share/* plus /gdoc/publish).

Self-maintaining — two CI lints keep the docs honest

This is what makes the master index trustworthy enough to rely on:

  • tests/unit/lint/amc-control-route-coverage.test.ts scans the server source (src/main/services/cli/cli-server*.ts) for every registered route — including the lifecycle ROUTE_TABLE template and the url === / parseCliPath special cases — and asserts that each one is either documented as a row in endpoint-index.md or named on the inherited-debt list in amc-control-doc-debt-baseline.ts. Add a route and forget to document it, and the build fails naming the exact missing route and the route family's .claude/endpoint-descriptions/endpoint-descriptions-<family>.json entry to add (the family files live beside the skills tree, not inside the skill — Claude Code walks every file under a skill at every turn start). The table itself is generated (npm run endpoint-index:reindex) from that sidecar plus a derived Auth column, so a hand-added row is reverted by the next reindex. Document a route that no longer exists, and it fails naming the phantom row. That debt list is a hand-maintained constant that is meant to only shrink — nothing pins its size, so a deliberate line on it is the one legal way for a served route to stay undocumented. It also carries a self-alerting guard: the moment a developer adds a new url === '/foo' branch or a new parseCliPath action the scanner can't see, the guard fails and tells them to register it.
  • tests/unit/lint/amc-control-doc-structure.test.ts pins the architecture bidirectionally: every surface the index references exists as a flat top-level .md; every surface doc is referenced by the index (no orphans); every surface doc is linked from the hub (reachable in one hop); every hub link resolves; the hub wires the endpoint-index.md escape hatch; and every spoke carries the house-style minimum (an ## Endpoints heading + a Read [SKILL.md](SKILL.md) backlink).

Together they mean a future developer cannot add a CLI route, rename one, or remove a spoke without the docs being forced back into agreement — the failure messages tell them exactly what to fix.

Bundled-skills installer

On every launch, Omniscio's main process calls ensureBundledSkills() from /src/main/services/bundled-skills-installer.ts. The installer reads every top-level *.md file in the source dir (subdirectories are intentionally skipped — which is why the architecture is strictly flat), hashes them, and syncs to ~/.claude/skills/omniscio-control/ only when the hash changes. A .amc-managed.json marker records { installedBy, version, installedAt, sourceHash }; a foreign marker (user hand-edit) is left untouched. The opt-out is Settings → Workflow → Sync skills to Claude Code (defaults to on). The omniscio-control manifest in /src/shared/integrations/omniscio-control.ts (cliSkillIds: ['omniscio-control', 'omniscio-sessions', 'omniscio-scheduling', 'omniscio-automation', 'omniscio-content', 'omniscio-settings', 'omniscio-inbox', 'omniscio-observe'], llmDocPath: 'docs/llm-library/omniscio-control.md') is what registers the hub and the seven category skills — all eight install together as one bundle.

The hub can never be archived on its own. The seven category skills route into the hub's pages, so the manifest names it in requiredSkillIds: ['omniscio-control']. Every remove path refuses it (the Skills manager shows "Needed by 7 other Omniscio skills, so it can't be removed", the Skill Overhead card never offers it, and DELETE /skills/:id / POST /skills/bloat/archive answer 400 before any approval card is queued), and the installer ignores an old archive entry for it — a machine that archived it before this rule existed gets the whole current hub back on its next launch, along with a working amc-control stub in place of any broken leftover link. Background: bug report 5fd2eaf0, where an archived hub left all seven companions linking into nothing for about ten days. Rules: bundled-skill-feature-gating-contract.md.

Approval model — what the user actually sees

When an AI sends an approval-gated request (say PATCH /settings/typingIndicatorEnabled with { value: false }):

  1. The server inserts a cli_pending_actions row (actionKind, targetId, payload, previewText, clientRequestId, status: 'pending').
  2. It returns 202 Accepted with the new row id.
  3. The renderer reloads and shows an inbox card: "Set 'Typing indicator' to 'off'?" with Approve / Reject.

On Approve, Omniscio re-validates the payload against the live Zod schema and then applies it — even a tampered DB row must pass the live check. In-app sessions (Omniscio's own session token) get a bypass: 200 OK { applied: true } flat, no inbox round-trip. This never fires for external agents.

Idempotency — X-Client-Request-Id

Every approval-gated mutation accepts a client-supplied request id (clientRequestId in the body, or the X-Client-Request-Id header for bodyless routes). A second call with the same id for the same action_kind within 30 days returns the existing pending row instead of queuing a duplicate — so a network-hiccup retry is safe.

Related

Last verified 2026-09-28