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.

Two directions in one plane:

  • Inbound — the platform is an MCP server: point any MCP client at it and get the whole platform (execute agents, workflows, discovery, …) as MCP tools.
  • Outbound — the platform is an MCP client on your behalf: open a "run" against third-party MCP servers from the catalog and call their tools through one metered, tenant-isolated door.

Auth: Authorization: Bearer ozk_YOUR_KEY on every route here.

Inbound — use the platform from any MCP client

Canonical Streamable-HTTP endpoints (both accept an ozk_ bearer):

  • https://mcp.plungeai.com/v1 — the dedicated MCP host
  • https://api.plungeai.com/v1/mcp — the same surface through the One API router

Claude Code:

claude mcp add plungeai --transport http https://mcp.plungeai.com/v1 \
  --header "Authorization: Bearer ozk_YOUR_KEY"

Generic mcpServers JSON (Cursor, clients with config files):

{
  "mcpServers": {
    "plungeai": {
      "type": "http",
      "url": "https://mcp.plungeai.com/v1",
      "headers": { "Authorization": "Bearer ozk_YOUR_KEY" }
    }
  }
}

Per-client install steps (Claude Desktop, Cursor variants, VS Code, …) are the per-editor plungeai-in-* skills' job (e.g. plungeai-in-cursor); this file covers the HTTP surface.

Raw JSON-RPC 2.0 works too — POST /v1/mcp with the message as the body; responses come back as JSON, or SSE for streamed tool calls. The Mcp-Session-Id header is forwarded both ways — session-based flows must replay the one the server returns.

GET /v1/mcp/tools — what the platform exposes as MCP tools

Returns the standard JSON-RPC tools/list result (tool names like plungeai_execute_workflow, plungeai_execute_agent, …). List it live — the tool set evolves; never hardcode names or counts.

curl -s https://api.plungeai.com/v1/mcp/tools \
  -H "Authorization: Bearer ozk_YOUR_KEY"
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      { "name": "plungeai_execute_agent",
        "description": "Execute a platform agent with a prompt",
        "inputSchema": { "type": "object", "properties": { "...": "..." } } },
      { "name": "plungeai_execute_workflow", "description": "...", "inputSchema": { "...": "..." } }
    ]
  }
}

Outbound — MCP runs

Lifecycle: open a run → list/call its tools → close it. Runs are tenant-isolated (scoped to your key's identity) and expire after 30 idle minutes; close them explicitly when done anyway.

Find server_ids in the catalog first: GET /v1/discovery/search?kind=mcp-servers&q=<what you need> (plungeai-discovery) — ids come from there, never from memory.

POST /v1/mcp/runs — open a run

Body: {"server_ids": ["<registry mcp-server card id>", ...]}.

curl -s -X POST https://api.plungeai.com/v1/mcp/runs \
  -H "Authorization: Bearer ozk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"server_ids": ["cloudflare-docs"]}'

HTTP 201:

{
  "run_id": "00000000-0000-4000-8000-000000000007",
  "tools": [
    { "name": "mcp__cloudflare-docs__search_cloudflare_documentation",
      "description": "Search Cloudflare documentation",
      "input_schema": { "type": "object", "properties": { "query": { "type": "string" } } } }
  ],
  "connected": ["cloudflare-docs"],
  "failed": [],
  "warnings": [],
  "skipped": []
}

Tool names are namespaced mcp__<server>__<tool>. Partial success is real: check connected vs failed vs skipped — a run can open with some servers up and others down (per-server errors are in failed).

Errors: 400 invalid_body (missing/empty server_ids), 502 no_servers_connected — none of the requested servers came up; the body carries per-server failures plus the same skipped array. A server that just failed sits in a 60s cooldown: re-opening immediately lists it in skipped (not re-attempted) while other servers connect normally. Wait out the cooldown before retrying it.

GET /v1/mcp/runs/{id}/tools — the run's tool table

curl -s https://api.plungeai.com/v1/mcp/runs/00000000-0000-4000-8000-000000000005/tools \
  -H "Authorization: Bearer ozk_YOUR_KEY"
{
  "tools": [ { "name": "mcp__cloudflare-docs__search_cloudflare_documentation",
               "description": "...", "input_schema": { "...": "..." } } ],
  "count": 1
}

An unknown or expired run id is not a 404 here — it returns an empty tool table. Empty tools on a run you opened a while ago means the 30-idle-minute expiry hit: reopen the run.

POST /v1/mcp/runs/{id}/call — call one tool

Body: {"name": "<namespaced tool>", "args"?: object, "timeout_ms"?: integer}.

curl -s -X POST https://api.plungeai.com/v1/mcp/runs/00000000-0000-4000-8000-000000000005/call \
  -H "Authorization: Bearer ozk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "mcp__cloudflare-docs__search_cloudflare_documentation",
       "args": {"query": "durable objects alarms"}}'
{ "content": "# Search results\n\n1. Durable Objects Alarms — ..." }

Errors: 400 invalid_body (no name), 502 tool_call_failed — the message is always the fixed string "MCP tool call failed"; the upstream detail lives in the error envelope's content extra. One retry with backoff is reasonable, with one exception: a content of "no MCP servers are connected for this run (inject was not called, or state expired)" means the run id is unknown or idle-expired — reopen the run, don't debug the tool name.

DELETE /v1/mcp/runs/{id} — close a run

Idempotent — deleting an already-gone run still returns success.

curl -s -X DELETE https://api.plungeai.com/v1/mcp/runs/00000000-0000-4000-8000-000000000005 \
  -H "Authorization: Bearer ozk_YOUR_KEY"
{ "success": true }

Full outbound pattern (TypeScript, plain fetch)

const BASE = 'https://api.plungeai.com'
const H = { Authorization: `Bearer ${process.env.PLUNGEAI_API_KEY}`, // ozk_YOUR_KEY
            'Content-Type': 'application/json' }

// 1. open
const run = await (await fetch(`${BASE}/v1/mcp/runs`, {
  method: 'POST', headers: H,
  body: JSON.stringify({ server_ids: ['cloudflare-docs'] }),
})).json()
if (!run.connected?.length) throw new Error(JSON.stringify(run.failed))

// 2. call (tool name taken from run.tools — never hardcoded)
const tool = run.tools[0].name
const res = await (await fetch(`${BASE}/v1/mcp/runs/${run.run_id}/call`, {
  method: 'POST', headers: H,
  body: JSON.stringify({ name: tool, args: { query: 'workers kv limits' } }),
})).json()
console.log(res.content)

// 3. close
await fetch(`${BASE}/v1/mcp/runs/${run.run_id}`, { method: 'DELETE', headers: H })

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.