---
name: plungeai-tools-connectors
description: "Call PlungeAI structured tool-agents with typed parameters against a published invocation contract: fetch the contract (`plungeai_get_tool_contract` / `GET /v1/tools/{id}`), execute with typed `params` (`plungeai_execute_tool` / `POST /v1/tools/{id}/execute`), read live connected-account/credential status, and handle the trust fence (gated/money operations refuse unattended — `403 refused` on REST, `needs_approval`/`needs_connection` outcomes on MCP). Use when a card has a Parameters table (document conversion, weather, data-table CRUD, calendar, payments, posting), before the first call to an unfamiliar tool, or when fixing a `422 invalid_params` / `403 refused` / `needs_connection` response. For prompt-driven agents use `plungeai-agents`; for finding a tool id or contract use `plungeai-discovery`; for the model catalog use `plungeai-models`."
---

# PlungeAI Tools & Connectors

A **tool** is a structured agent: instead of free-text prompts it takes
**typed parameters** against a published contract — named operations, a JSON
Schema for inputs, worked examples, per-operation approval gates, and (over
MCP) the acting user's live credential status. The rule that prevents almost
every tool failure: **fetch the contract before the first call to an
unfamiliar tool — the contract IS the API documentation.**

## Prerequisites

- Self-service `ozk_` key from **Dashboard → One API → Keys**
  (`https://dashboard.plungeai.com`).
- MCP: `https://mcp.plungeai.com/v1`. REST: `https://api.plungeai.com`.

## Discovery first

Find the tool (`plungeai_list_agents {search}` / `GET /v1/discovery/search`,
see `plungeai-discovery`), then fetch its contract:

```json
plungeai_get_tool_contract {agent_id: "markitdown"}
```

```bash
curl -s https://api.plungeai.com/v1/tools/markitdown -H "Authorization: Bearer ozk_YOUR_KEY"
```

Read it in order: `operations` (pick by `purpose`; note `gated: true`),
`inputSchema` (exact param shapes), `examples` (worked CNL), then —
MCP contract only — the **Credentials** section (see below).

## Execute — MCP

```json
plungeai_execute_tool {
  agent_id: "markitdown",
  operation: "convert",
  params: { file_data: "<base64 of the file>", file_name: "report.pdf" }
}
```

Answers a structured outcome envelope over HTTP 200, always — `ok` \|
`needs_input` \| `needs_connection` \| `needs_api_key` \| `needs_approval` \|
`unavailable` \| `error`. Full parameter table and the outcome table —
`references/mcp-execute-tool.md`.

## Execute — REST

```bash
curl -s -X POST https://api.plungeai.com/v1/tools/brave-agent/execute \
  -H "Authorization: Bearer ozk_YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"operation": "search", "params": {"query": "cloudflare workers pricing"}}'
```

Same fences, REST spelling: `403 refused` (fence — never retry),
`404 unknown_tool`, `409 approval_required` (a dispatched run's own outcome
paused for approval — approve out-of-band in Studio, then re-issue the
identical request; REST has no continuation token like MCP's
`plungeai_continue`), `422 invalid_params` (body carries `missing` + the
full contract — self-correct and retry once). Full error catalogue, the 403
fence-vs-lifecycle distinction, streaming/format —
`references/rest-tools-plane.md` and `references/contract-and-execution.md`.

## Connected accounts (credential status)

The contract's Credentials section is LIVE per acting user:

- `🔐 platform-managed` — nothing to connect.
- `✅ connected as <email>` — call away.
- `⚠️ NOT connected` / `expired — reconnect` — execution answers
  `needs_connection`/`needs_api_key` (MCP) or `424 connection_required`
  (REST) until the user connects it in a PlungeAI app (Studio → Connectors).
  Relay exactly what to connect; retry the identical call after.

## Why the fences exist

Gated operations are the ones with real-world blast radius: money movement,
outbound messages, irreversible mutations. **An unattended caller never
fires them** — a human must be in the loop. `403`/`409`/`needs_approval` are
correct behavior, not errors to engineer around: surface them, get the human
decision, continue through the approval mechanism (`plungeai_continue` on
MCP). A retried tool call re-fires the FULL operation — check execution
history before re-firing anything non-idempotent.

## Gotchas

- **Reserved param names** (`agent`, `type`, `id`, `operation`, `depth`,
  `user_id`, `executor_user_id`, `workflow`, `execution_id`) collide with the
  task envelope and are never forwardable — `needs_input`/`422` names them.
- **A lone `prompt` on a multi-operation card runs the DEFAULT operation**
  and warns about it — if that's not what the user meant, re-call with an
  explicit `operation` + typed `params`.
- **`gated: true` is refused regardless of operation wording** — rephrasing
  the prompt or switching styles to sneak past a fence never works.
- **`409 approval_required` IS real on REST** — it fires when a dispatched
  run's own outcome comes back `needs_approval`, not from the pre-dispatch
  gated-verb/guarded-category fence (that fence runs in unattended mode on
  this route and always resolves to `403 refused` instead). Approve
  out-of-band, then re-issue the identical request.

## Related skills

- `plungeai-discovery` — search, full cards, the contract fetch itself.
- `plungeai-agents` — prompt-driven execution, `plungeai_get_result`.
- `plungeai-models` — model/provider overrides, the money plane.
- `plungeai-workflows` — put a tool's typed fields directly on a CNL task.
- `plungeai-results-traces` — tracing an `execution_failed`/`upstream_error`.
