---
name: plungeai-in-v0
description: "Connect v0 (Vercel) to PlungeAI (Ocean Studio) over MCP — the + menu → MCPs form, why the generated Next.js app must call PlungeAI through a server Route Handler (v0 apps can't call MCP directly), and a plungeai_whoami + plungeai_list_agents verify. Use when the user is in v0 and says connect / install / set up PlungeAI, mentions the MCPs panel, or a generated v0 app 401s against PlungeAI. For another builder use its plungeai-in-<tool> skill; for an unlisted but MCP-capable client use plungeai-mcp-setup's generic client config."
---

# PlungeAI in v0 (Vercel)

v0 is a hosted builder: no local config file and no JSON entry anywhere —
the MCP form is the only surface, and the key lives only in that entry.

## Prerequisites

- An `ozk_` key: Dashboard → **One API → Keys** (https://dashboard.plungeai.com) —
  self-service, shown once, copy it now.

## Connect (once)

Open the **+** menu in the prompt form → **MCPs** → add your own server (the
project settings page offers the same via **Add MCP**):

| Field | Value |
|---|---|
| Name | `PlungeAI` |
| URL | `https://mcp.plungeai.com/v1` |
| Authentication | **Bearer Token** → paste the `ozk_` key itself (v0 adds the `Bearer` prefix); or **Custom Headers** → `Authorization` = `Bearer ozk_YOUR_KEY`. If one form 401s, try the other. (`No Auth` and `OAuth` don't apply — PlungeAI OAuth hasn't shipped.) |

Then pick the server's **permission mode**: **Disabled**, **Ask for
Approval (Manual)**, or **Always Run (Auto)**. Manual is the sane default;
money-verb PlungeAI operations still pause with a structured
`needs_approval` outcome even under Auto — relay it, then
`plungeai_continue`.

## The generated app cannot call MCP

v0's generated code cannot use the MCP tools directly — pair the MCP with
**Environment Variables**. So the split is: the builder chat operates
PlungeAI over MCP; the generated Next.js app calls the One API server-side
only, e.g. a Route Handler:

    // app/api/plungeai/route.ts
    export async function POST(req: Request) {
      const { input, agentId } = await req.json()
      const r = await fetch(
        `https://api.plungeai.com/v1/agents/${agentId}/execute`,
        {
          method: "POST",
          headers: {
            Authorization: `Bearer ${process.env.PLUNGEAI_API_KEY}`,
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ input, sync: true }),
        },
      )
      return Response.json(await r.json())
    }

Key in a Vercel env var (`PLUNGEAI_API_KEY`, every environment that needs
it), never in client components, never prefixed `NEXT_PUBLIC_`.

## Verify

1. Builder chat: "use plungeai_whoami to confirm my identity" → an
   identity card.
2. Generated app (server side):
   `curl -H "Authorization: Bearer ozk_YOUR_KEY" https://api.plungeai.com/v1/agents`
   → HTTP 200 JSON.
3. "use plungeai_list_agents to search 'web search'" → live results from
   the active agent catalog.

## Quirks

- v0 previews run without the project's env vars until linked/deployed — a
  preview 401 from the app does not mean the integration is wrong; verify
  with the curl check above, then set the env var on the Vercel project.
- If generation puts the fetch in a `"use client"` component, regenerate
  with: "PlungeAI calls go through a Route Handler; the key stays
  server-side."
- Long CNL workflows: prefer async mode
  (`plungeai_execute_workflow` with `mode: "async"` +
  `plungeai_get_workflow_status`) over one long synchronous builder-chat
  call.

## Where next

- Writing the Route Handler / server code that calls `https://api.plungeai.com`: **plungeai-api-setup**.
- Operating the `plungeai_*` tools in chat: **plungeai-mcp-setup**.
- Picking MCP vs the One API for a given job: **choose-your-plungeai-door**.
- An unlisted but MCP-capable client, or the shared connect concepts (native
  remote vs. stdio bridge, key hygiene): **plungeai-mcp-setup**.
