For AI agents: a documentation index is available at https://docs.plungeai.com/llms.txt. Append .md to any page URL, or send Accept: text/markdown, to get markdown. Setup instructions for agents are at https://docs.plungeai.com/agents.md. One ozk_ key opens every plane, models included.

Documentation Index: fetch the complete documentation index at /llms.txt. Use this file to discover all available pages before exploring further.

Design and emit ONE PlungeAI (Ocean Studio) bot agent — a scheduled, unattended type: harness mission that reports to the user's channels (in-app, email, Slack, Telegram, WhatsApp, Discord) — as CNL YAML plus a bot-config block (cron schedule, delivery targets, optional run-on-my-computer). Use when the Studio Think composer has "Bot agent" selected, or when a user asks for a bot, a scheduled agent, a daily/weekly brief, a watcher, a monitor, a digest, or "something that runs on its own and tells me". Triggers: "bot", "every morning", "schedule", "report to Slack", "watch and alert", "digest". NOT for interactive agents (plungeai-agentic-agent) or multi-task pipelines (plungeai-workflows).

Download zip (opens in a new tab) · View raw SKILL.md (opens in a new tab)

Used by Studio: Ocean Studio's agent builder loads this skill by its id.

A bot is an agentic agent with three extra facts: WHEN it runs, WHERE the result goes, and whether its hands are the user's own computer. Studio saves the mission under "Bots" and creates the schedule + delivery from your bot-config block. Unattended runs cannot ask the user anything: no ask_user, no platform_action, and every risky tool is either excluded or permissions: deny.

The conversation (before any YAML)

  1. Job. One sentence: what the bot produces each run (a brief, an alert, a digest).
  2. Cadence. Ask for the schedule in words, propose the cron, confirm it. Five fields, UTC unless the user gives a timezone (convert and say so).
  3. Where it reports. Ask which channels: inapp (Studio inbox, always safe), email (owner or listed addresses), slack (DM the owner or a channel id), telegram, whatsapp, discord (require a paired chat — say the user must pair first if unsure). Default inapp when the user has no preference.
  4. Hands. Cloud (default) or "runs on this computer" (local: true) when it must read local files, control local apps, or use local agents. Local bots pin agent: harness-agent.
  5. Fence + capabilities + budget exactly as for an agentic agent: smallest allowed_tools, ids only from AVAILABLE CAPABILITIES and live registry_search, effort: standard unless argued, 2–4 success_criteria.

Confirm, then emit BOTH blocks.

Output contract — two fenced blocks, in this order

workflow:
  name: "<short bot name>"
  description: "<one line: what it reports and how often>"
  tasks:
    - type: harness
      id: bot
      agent: harness-agent
      goal: "{input}"
      mission: |
        You are <name>, a bot that <job>. Each run you <steps in 2–4 sentences>.
        Output <format: bullets / table / one paragraph>. Keep it under <n> words.
        End with `[SILENT]` (or make your whole result `[SILENT]`) when nothing is worth
        reporting this run — the platform then delivers to no channel.
        When your task is finished, call the task_complete tool with your final result.
      effort: standard
      allowed_tools: [web_search, web_fetch, task_complete]
      success_criteria:
        - <statement the bot verifies before finishing>
schedule: "0 7 * * 1-5"
deliver:
  - channel: inapp
  - channel: slack
    chat_id: C0123ABCD
local: false
prompt: "<the per-run input the schedule sends as {input}>"

Rules the lint enforces — violating them makes the save fail:

  • ONE task, type: harness, agent: harness-agent (one-agent when it uses the always-on abilities below), goal: "{input}", mission ends with the task_complete sentence.
  • allowed_tools MUST include task_complete and MUST NOT include ask_user or platform_action (nobody is there to answer). skill_manage needs permissions: {skill_manage: allow} to run unattended — leave it out unless asked.
  • No memory_owner (the platform scopes bot memory itself). No emails or ids in the YAML; recipients belong in bot-config deliver, not in the mission.
  • local: true goes in BOTH blocks — on the harness task (the runtime reads it to route tool calls to the machine) and in bot-config (so the scheduler skips cleanly when the machine is offline) — and only with agent: harness-agent; add local_agents: [ids] from the user's connected local agents when they name them, else leave it out (all connected agents).

bot-config fields

  • schedule — 5-field cron, required. Examples: 0 7 * * 1-5 weekdays 07:00, */30 * * * * every 30 min, 0 18 * * 5 Fridays 18:00.
  • deliver — list of {channel, chat_id?, to?, phone_number_id?}: inapp (no fields), email (to optional = owner), slack (chat_id C… channel or to U… member; none = DM the owner), telegram/discord (chat_id), whatsapp (to number + phone_number_id). Default [{channel: inapp}].
  • local — true only for run-on-my-computer bots. Default false.
  • prompt — the per-run input. Default empty (the mission's goal alone drives the run).
  • budget_usd_run / budget_usd_month — optional non-negative spend caps. Per-run stops the loop once its token cost exceeds the cap; per-month is enforced by the scheduler.
  • permissions — optional class presets { pay|send|write|delete: ask|allow|deny } persisted on the bot. pay: ask is the safe default for anything money-adjacent. allow lets that class run automatically unattended, but never lowers the money floor (buy, pay, transfer, send, withdraw, … always pause for approval, even with pay: allow). A team admin can LOCK a class from the Studio Permissions dialog, which forces its allow back up to ask.

Permissions — approval rules

Per-tool permissions on the mission gate individual tools. Per-CLASS presets (bot-config permissions, or the ⋮ → Permissions dialog) gate whole action classes. The order the loop resolves a call: the money floor (always ask), then an admin lock, then the tool-name preset, then the class preset, then allow. On agent: one-agent the order is deny first, then the money floor, then ask, then the tool preset, then the class preset, then allow; an admin lock only lifts allow to ask. Safe default for a bot that touches money or deletes: permissions: { pay: ask, delete: ask }. An unattended pay: allow proceeds automatically for non-floor money ops; a floor op still pauses to needs_approval (the run can sit up to 7 days awaiting the owner) — the [SILENT] output contract must never suppress that pause notice.

Always-on abilities (agent: one-agent)

When the user wants the bot to manage its own schedule, talk to other bots, browse a site it logs in to, or run under tighter controls, emit agent: one-agent (instead of harness-agent) on the harness task and use these. All are opt-in; leave them out unless the user asks.

  • Tools (add to allowed_tools, each needs a saved bot):
    • schedule — action: create | list | pause | resume | delete | run_now | wake. create {name, cron | '@once', in?, timezone?, prompt?, deliver?, ends_at?}; wake {in, note} re-runs the bot once (at least 60 s). The bot writes the cron itself and must say the schedule back in words.
    • message_bot — {to: <bot name | id | 'a2a:<url>'>, text, wait?: boolean}. to must be in peers. Replies are asynchronous: they reach the sender as [MESSAGE from <bot>] at the start of a later run (wait: true runs the bot now instead).
    • browser — {steps, url?, session?: 'bot' | 'none'}; session: 'bot' keeps the bot's cookies between runs. Steps that click, type or press keys count as writes.
    • memory — action: forget {query} removes matching memory entries.
  • Mission keys (on the harness task, snake_case): peers: [bot names | ids | "a2a:<url>"] (the only bots message_bot may reach; none by default), posture: read_only (denies write, send, delete, pay), review: auto (a model reviews each allowed write / send / pay / delete call; costs one call each), max_runtime_s: <seconds> (wall-clock cap), workspace: run | bot (default bot for a saved bot: its files persist across runs; run starts clean).
  • Limits to know:
    • message_bot wait: true runs the target as a plain child run (depth + 1, skip_memory): no memory, no inbox, no bot workspace, no bot tools. Use wait: false for the full bot.
    • Shared bots: the always-on abilities (inbox, schedule, message_bot, the browser bot session, the persistent workspace) are owner-only; a teammate runs a shared bot without identity.
    • A saved non-bot workflow that uses agent: one-agent and is run by its owner is treated like a bot (persistent bot:<id> workspace by default, bot tools available): the engine derives the identity for every saved workflow.
    • posture: read_only also denies delegate, invoke_workflow and every MCP tool (an unknown class fails closed). An off-contract posture or review value is forced to read_only / auto; it never widens a run.

The fence for unattended runs

Allowed vocabulary is the same 24 loop tools as an agentic agent; read plungeai-agentic-agent for the catalog. Bots add these rules: exclude ask_user, platform_action; prefer read paths (web_search web_fetch read_file recall_history knowledge) plus the agents the job needs via call_agent with a tight allowed_agents; anything that sends or pays needs the user's explicit yes in the conversation AND stays permissions: deny unless they insist. Delivery of the result is NOT a tool — the platform delivers task_complete's result to the deliver targets.

Read references/bot-config.md for delivery pairing and the platform behaviour on failure.

Outside Studio the same bot ships over MCP (https://mcp.plungeai.com/v1): plungeai_schedule with action: create, job_type: workflow creates the job against a saved workflow. Discover the agent ids you fence into allowed_agents live — plungeai_list_agents from a client, or registry_search inside the loop — never from memory.

Reference pages

Planned: TI-33

Search is not available yet. Until it ships, use the page index or browse the sidebar.

Planned: TI-34

The docs assistant is not available yet. You can hand these docs to your own assistant instead.