MCP
Quickstart
Source: orchestration/mcp-gateway/index.ts, server.ts, extras.ts (plungeai_whoami), tools.ts (listAgents, executeAgent), tool-outcome.ts, prompts.ts, integrations.ts; apps/ocean-skills/skills/plungeai-in-claude-code/SKILL.md; MCP SDK webStandardStreamableHttp.js (SSE framing). Unauthenticated responses live-verified 2026-09-24.
Five minutes from nothing to a real run. The endpoint is https://mcp.plungeai.com/v1; https://api.plungeai.com/v1/mcp is the same server if you prefer the One API host (0.2).
1.1 Get a key
- Sign in at
https://dashboard.plungeai.com→ One API → Keys → create a key. Give it a name and pick an expiry (never, or 7 / 30 / 90 / 180 / 365 days). - Copy it now. It starts with
ozk_live_and is shown exactly once. - Put it in your shell for the examples in this guide:
export PLUNGE_API_KEY=ozk_… # paste your key; never commit itKey details (tiers, expiry, revocation, fences): Authentication & keys.
1.2 Connect Claude Code (one command)
claude mcp add --transport http plungeai https://mcp.plungeai.com/v1 \
--header "Authorization: Bearer $PLUNGE_API_KEY" --scope user--scope usermakes the server available in every project. Without it, the default scope islocal(this project only). Both are stored in~/.claude.json, outside your repo.- Never use
--scope projectwith a literal key: that writes the key into.mcp.jsoninside the repo.
Check it: claude mcp list (or /mcp inside a session) shows plungeai connected. Then ask Claude:
use plungeai_whoami to confirm my identity
You get an identity card: user id, auth type and tier, key label, rate-limit window, server. Every other client is in Connecting clients.
1.3 Or: a project .mcp.json
To share the server definition with a team, commit an .mcp.json that reads the key from each developer's environment instead of holding it:
{
"mcpServers": {
"plungeai": {
"type": "http",
"url": "https://mcp.plungeai.com/v1",
"headers": { "Authorization": "Bearer ${PLUNGE_API_KEY}" }
}
}
}Each developer exports PLUNGE_API_KEY before starting Claude Code. The same mcpServers shape works in other JSON-configured clients, with small per-client differences (Connecting clients). If you write a literal key into a file instead ("Bearer ozk_YOUR_KEY"), keep that file out of git.
1.4 Raw HTTP: initialize → tools/list → tools/call
No client needed. The server speaks JSON-RPC 2.0 over Streamable HTTP, and it is stateless: send each call on its own, no session id. initialize is what a client sends first; you can skip it with curl and go straight to tools/list.
Step 1 — initialize. The answer is plain JSON: the negotiated protocol version, the capabilities (tools, resources, prompts, logging), serverInfo (plungeai.com) and the server's usage instructions for AI clients.
curl -s https://mcp.plungeai.com/v1 \
-H "Authorization: Bearer $PLUNGE_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'Step 2 — tools/list. Plain JSON again: every tool with its description, its inputSchema (JSON Schema) and, for some, an outputSchema and a readOnlyHint. The full answer is long; this prints only the names:
curl -s https://mcp.plungeai.com/v1 \
-H "Authorization: Bearer $PLUNGE_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
| python3 -c 'import json,sys; print("\n".join(t["name"] for t in json.load(sys.stdin)["result"]["tools"]))'You see 22 names, plungeai_execute_workflow first and plungeai_connections last. A key with a tool fence sees fewer (2.5).
Step 3 — tools/call plungeai_whoami. Read-only and free (it still counts as one call toward your rate limit):
curl -s https://mcp.plungeai.com/v1 \
-H "Authorization: Bearer $PLUNGE_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"plungeai_whoami","arguments":{"user_request":"who am I"}}}'A tools/call always answers as a server-sent-event stream, even a quick one:
event: message
data: {"result":{"content":[{"type":"text","text":"# Who am I\n\n- **User:** `…`\n- **Auth:** api-key · tier **pro**\n- **Key:** my-laptop (`…`)\n- **Rate window:** 1/min used · 1/day used\n- **Server:** plungeai.com (mcp.plungeai.com)","annotations":{…}}],"isError":false},"jsonrpc":"2.0","id":3}Longer calls send notifications/message (or notifications/progress) events first, then the result. The data: line of the last event is the JSON-RPC response.
Reading a tools/call answer
Pipe any tools/call through this to print just the rendered text of the final result:
… | sed -n 's/^data: //p' | tail -1 \
| python3 -c 'import json,sys; r=json.load(sys.stdin)["result"]; print(r["content"][0]["text"])'Notes:
user_requestis optional on every tool, but pass it: it is the user's request in their own words, and the platform uses it for routing and support diagnostics. Clients are told to send it on every call.- If you leave out the
Acceptheader, the server fills it in for you. MCP clients always send it. - A
401here means the key did not reach the server or is not valid — 2.3.
1.5 Your first real run
Find an agent. Discovery is free. search is a hybrid semantic and keyword query, so describe the capability in plain words:
curl -s https://mcp.plungeai.com/v1 \
-H "Authorization: Bearer $PLUNGE_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"plungeai_list_agents","arguments":{"user_request":"what agents can search the web?","search":"web search","limit":3}}}'Each match is a registry card: id, category, what it is good at, and "Not for → use X instead" redirects. Take agent ids from a search like this, never from memory — an id that is not active is refused at execution (Discovery).
Run one. This calls one-agent, the platform's agent runtime, once. It runs a model, so it costs credits (no # verify marker):
curl -s https://mcp.plungeai.com/v1 \
-H "Authorization: Bearer $PLUNGE_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"plungeai_execute_agent","arguments":{"user_request":"what is a CDN, in one sentence","agent":"one-agent","prompt":"In one sentence: what is a content delivery network?","max_tokens":80}}}'While it runs, progress events arrive first (lines such as ⚙️ Agents working — 0/1 agents complete or ✍️ Writing (212 chars) — …). The final result's text is the answer, then a footer:
---
execution: `3f0c…` — use this id for plungeai_get_result / plungeai_followup on this run.Its structuredContent is the outcome object {"status":"ok","summary":"Agent completed.","result":"…","execution_id":"…"}. The run now appears in your execution history in Studio and the dashboard.
Read it again. plungeai_get_result fetches any of your runs by that execution id (read-only):
curl -s https://mcp.plungeai.com/v1 \
-H "Authorization: Bearer $PLUNGE_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":6,"method":"tools/call","params":{"name":"plungeai_get_result","arguments":{"user_request":"show me that result again","execution_id":"PASTE_EXECUTION_ID"}}}'An id that is not one of yours comes back as needs_input naming the id — not a bare "not found" (Runs, results & follow-ups).
In a client you would simply ask: "Ask one-agent in one sentence what a Cloudflare Durable Object is.", then "Show me the result of that last run."
1.6 What to try next
The /plungeai prompt. In Claude Code, type /plungeai and pick /plungeai:plungeai (MCP) from the menu. Run it bare, then type your request as the next message: Claude Code passes only the first word of any text typed after the command. You can also just talk normally — the prompt is a convenience (Prompts & resources).
Things to ask, as normal sentences:
| Try asking | What happens | Chapter |
|---|---|---|
| "What agents do you have for financial analysis and SEC filings?" | semantic registry search | Discovery |
| "Give me a five-day weather forecast for Sun Valley, including air quality." | the client reads weather-agent's contract and runs it with typed fields | Tools |
| "Ask your harness agent a quick question: what's notable about Sun Valley, Idaho?" | a bounded one-shot mission | Agents & missions |
| "Show me all the workflows in my Finance folder." · "Run the Acquisition Scanner with Adobe as the input." | lists and runs your workflows | Workflows |
| "Build me a workflow that scans a company for acquisition news and writes a briefing." | generates and saves a CNL workflow from real registry agents | Workflows |
| "Is that still running?" · "Show me my last 10 executions." | status and run history | Runs, results & follow-ups |
| "Remember that our fiscal year ends in June." | writes durable memory | Chat, memory & skills |
| "Run the S&P 500 weekly performance analysis every Monday at 7am." | creates a cron schedule | Scheduling |
| "Who am I, what tier am I on, and how much of my rate limit have I used?" | plungeai_whoami | Authentication & keys |
When a run pauses. Some runs stop before spending money or doing something irreversible and come back headed ⏸ NEEDS APPROVAL. Nothing has run yet. If the answer carries ⏸ AWAITING USER APPROVAL: …, an agent staged the action and paused: your client relays it, you answer "yes" or anything else, and the client continues with plungeai_continue. If it does not, the trust fence refused an outward operation (a send, a payment) outright: there is nothing to continue over MCP, and the operation runs only from Ocean Studio, where you approve it (6.6, Runs, results & follow-ups).
Long jobs. Ask for them to run "in the background": you get an execution id at once and ask for the status or result later (Workflows).