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. Execution planes take an ozk_ key; the models plane takes an sk-ocean- key.

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

plungeai_whoami

Purpose: show the authenticated identity — the ground truth for "who am I acting as" and "how much budget is left". Read-only, no arguments beyond user_request. Use it to verify a new connection, and whenever ownership ("Execution not found") or rate-limit errors appear.

Example: {"user_request": "verify my plungeai connection"}

Returns

# Who am I
- **User:** `<uuid>`
- **Auth:** api-key · tier **pro**
- **Key:** <label> (`<key id>`)
- **Rate window:** N/min used · M/day used
- **Server:** plungeai.com (mcp.plungeai.com)

Failures & fixes: "Authentication required." → the key never reached the server; fix the header (Authorization: Bearer ozk_YOUR_KEY or X-API-Key: ozk_YOUR_KEY). The rate window line is best-effort and may be absent — that alone is not an error.


The auth model

An API key IS a user identity. The key resolves to a user id, and every read/write on every tool is scoped to what that user owns — the same view that user has in Studio, never the whole system. Every id-based operation (executions, workflows, jobs, conversations, memory) is ownership-checked before any storage is read; a foreign id answers "not found", not "forbidden" — so a plausible-looking id that returns "Execution not found" usually belongs to someone else or is mistyped.

Auth order: an internal service path an API key can never reach → X-API-Key → Authorization: Bearer (personal API keys, e.g. ozk_YOUR_KEY; any other bearer value is rejected — logged as unsupported_bearer_token — only ozk_ keys authenticate, there is no OAuth token path today). Unauthenticated requests get 401 with a WWW-Authenticate: Bearer challenge (error="invalid_token" when credentials were supplied but invalid). Keys are self-service — mint your own at Dashboard → One API → Keys (https://dashboard.plungeai.com); an account owner can additionally fence (allowed_ips/allowed_tools) or revoke any key on the account, including a shared team key.

Per-key fences (both optional, set at mint):

  • allowed_ips — the key only authenticates from listed addresses/CIDRs; anywhere else is a 401 (and counts against failed-auth metering).
  • allowed_tools — other tools are HIDDEN from tools/list, and calling one returns -32602 Tool not permitted for this key. If a documented tool is missing from tools/list, the key is fenced — re-mint or edit the key's fence in the Dashboard; do not keep calling it.

Rate limits are per tier: free 30/min · 1k/day, pro 100/min · 10k/day, enterprise 300/min · 100k/day (tool calls only). Over-limit → HTTP 429 with a Retry-After header — wait that long, then resume; never tight-loop.

Activity trail: every request is recorded to a per-user daily log (arguments in full, answers as receipts). A user reads their own with their own key: https://mcp.plungeai.com/log?date=YYYY-MM-DD (Bearer header, or &key=ozk_YOUR_KEY in a browser). This is also why user_request matters: it is the one place the user's actual sentence survives into diagnostics.


Two error planes

1. Protocol errors (JSON-RPC, transport-level) — the request itself was rejected; no tool ran:

SignalMeaningYour move
401 + WWW-AuthenticateMissing/invalid/revoked key, or IP outside the key's fenceFix the credential; don't retry blind. Repeated failures meter the IP (429 with Retry-After).
429 + Retry-AfterRate limit (per-tier), or failed-auth meteringWait the stated seconds, resume, consider batching.
-32602 "Tool not found" / "Tool not permitted for this key"Typo'd tool name, or a key fenceRe-check against tools/list; if fenced, edit the key's fence in the Dashboard.
-32700 Parse error / 413 body too large (1 MiB)Malformed or oversized requestFix the payload; huge YAML belongs in a saved workflow, not inline.
405 / 403 invalid Host / -32603 internalTransport misuse or server faultUse POST to the canonical endpoint; internal errors: retry once, then report.

One deliberate crossover: arguments that fail a tool's own schema (e.g. limit: 200) are pre-screened BEFORE the tool runs and still answer in the envelope — needs_input, "<tool> was not called — its arguments do not match the tool's schema", with provide_field actions per bad field. Nothing ran; fix the named fields against the tool's inputSchema from tools/list.

2. Tool outcomes (the envelope) — the tool ran (or deliberately refused) and answered with structured guidance. Execution tools NEVER return a raw error: the answer is text plus structuredContent with

status: ok | needs_input | needs_connection | needs_api_key
      | needs_approval | unavailable | error
summary, agent_id?, operation?, result?, execution_id?,
missing?[], warnings?[], contract?,
remediation: { message, actions: [...] }

Typed remediation.actions tell you the exact next move: connect_provider (user opens the named URL and connects — needs their browser), provide_api_key (user saves a key in a PlungeAI app), provide_field (fix that field, retry the same call), approve_via / respond_via (the ⏸ loop → plungeai_continue), retry_with (retry with the stated changes, e.g. {mode: "async"}), use_alternative (a real, callable substitute agent id).

isError is true ONLY for terminal error outcomes. Every other non-ok status is guidance the model acts on — the response even ends with "This is structured guidance, not a crash — do not retry the identical call." Believe it.


The trust fences (surface, never retry, never bypass)

The active-only fence. Only status:active agents are listed and callable over MCP. plungeai_execute_agent, plungeai_execute_tool, ad-hoc YAML in plungeai_execute_workflow (including agents nested in parallel/sequential blocks), and plungeai_schedule create all refuse an unknown or inactive id BEFORE dispatch, writing no execution row. Every refusal's prose points you at plungeai_list_agents; plungeai_execute_agent and plungeai_execute_tool additionally attach live use_alternative suggestions to their unavailable envelope — plungeai_execute_workflow's fence refusal carries no remediation actions, and plungeai_schedule create answers with plain error text, not an envelope. A refusal is a policy answer, not a transient failure: always re-discover with plungeai_list_agents (semantic search), take a fresh id from the results, and never "retry" the refused id or guess a variant spelling.

The approval fence. Gated operations and real-world side effects pause as needs_approval / ⏸ AWAITING USER APPROVAL (a paused run also shows it in plungeai_get_workflow_status → continuation). This is a deliberate trust boundary between the platform and the human: relay it verbatim, let the USER decide, and only then plungeai_continue {approve: true} (yes) or {message: "<their words>"} (no / change). Approving on your own, retrying around the pause, or resubmitting the original call are all violations — the platform holds the pending action server-side until the user answers.

Connection fences. needs_connection / needs_api_key mean the USER must act in their browser (connect an account or save a key in a PlungeAI app, e.g. Studio → Connectors, per the remediation's URL). Relay the exact instructions, wait for their confirmation, then retry the IDENTICAL call — this is the one case where the same call is expected to be repeated, and only after the user acted.

Ownership answers. "not found / not one of your executions" on a plausible id is an ownership verdict, not a storage glitch — re-list (plungeai_executions, plungeai_list_workflows, plungeai_schedule {action: "list"}) and use an id the account actually owns.


Failure classification you can rely on

Whatever the pre-flight didn't predict, the engine's raw failure is classified into the same envelope — a named missing API key becomes needs_api_key, an upstream 401 becomes needs_connection naming the provider to connect, insufficient OAuth scopes become "reconnect to grant additional scopes", missing/invalid inputs become needs_input WITH the agent's contract attached, an undeployed binding becomes unavailable with alternatives, and a timeout becomes error with retry_with {mode: "async"}. A failed run always carries a reason — plungeai_get_result on a failed id answers "This run failed: <reason>" rather than a dead end. So: read the status, follow the remediation, and reserve blind one-time retries for the one class labeled transient ("This is a transient platform failure ... Retry once in a few seconds", stamped with a request id to report if it persists).

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.