agents
Use when designing, deploying, or debugging a Butterbase Agent (declarative LLM/tool graph), registering an MCP server for tool…
Use when building features that join, record, or transcribe Zoom/Meet/Teams/Webex calls — meeting bots, call notetakers, sales-call summarizers, interview transcribers. Covers ctx.ai.meetings.start/get/stop/list, webhook setup, and credit metering.
Claude Code
$ npx -y skills add butterbase-ai/butterbase-skills --skill meetings --agent claude-code
Codex
$ npx skills add butterbase-ai/butterbase-skills --skill meetings -a codex -y
Cursor
$ npx skills add butterbase-ai/butterbase-skills --skill meetings -a cursor -y
Gemini CLI
$ npx skills add butterbase-ai/butterbase-skills --skill meetings -a gemini-cli -y
GitHub Copilot
$ npx skills add butterbase-ai/butterbase-skills --skill meetings -a github-copilot -y
OpenCode
$ npx skills add butterbase-ai/butterbase-skills --skill meetings -a opencode -y
Windsurf
$ npx skills add butterbase-ai/butterbase-skills --skill meetings -a windsurf -y
name: meetings description: Use when building features that join, record, or transcribe Zoom/Meet/Teams/Webex calls — meeting bots, call notetakers, sales-call summarizers, interview transcribers. Covers ctx.ai.meetings.start/get/stop/list, webhook setup, and credit metering.
Guide for building features that spawn meeting bots via `ctx.ai.meetings`. Covers the four SDK methods, webhook handling, idempotency, and cost-aware design.
---
Reach for this skill when your feature involves any of:
If you need only audio/video file upload without a live meeting join, use `manage_storage` instead.
---
| Method | What it does | One-line example | |--------|-------------|-----------------| | `bb.ai.meetings.start(opts)` | Spawns a bot and returns immediately with `status: "joining"` | `const { data: bot } = await bb.ai.meetings.start({ meetingUrl, transcript: true })` | | `bb.ai.meetings.get(id)` | Fetches current status + artifact URLs | `const { data } = await bb.ai.meetings.get(bot.id)` | | `bb.ai.meetings.stop(id)` | Removes the bot from the call early | `await bb.ai.meetings.stop(bot.id)` | | `bb.ai.meetings.list(opts)` | Lists bots with optional `status`, `limit`, `cursor` filters | `await bb.ai.meetings.list({ status: 'done', limit: 50 })` |
All methods return `{ data, error }` — always check `error` before using `data`.
---
1. **Configure webhook** — call `manage_ai` with `action: "configure_meetings_webhook"`, passing `forward_url` pointing at a deployed Butterbase function or your own endpoint. 2. **Start the bot** — app calls `bb.ai.meetings.start(...)`. Status begins as `joining`. 3. **Bot joins** — status progresses `joining → waiting_room → in_call → recording`. The `bot.in_call_recording` event fires. 4. **Call ends** — bot status moves to `ended`, then `done` once artifacts are processed. 5. **Webhook fires `bot.done`** — your handler receives the event. The bot's `recordingUrl` and `transcriptUrl` are now populated. 6. **Fetch artifacts** — download the recording or transcript using the URLs from `bb.ai.meetings.get(id)`. 7. **Write to substrate / database** — store the transcript text, link to the relevant entity (deal, candidate, customer), or insert into a RAG collection. 8. **Trigger downstream extract** — run an LLM summarization, action-item extraction, or scoring job.
---
Deploy this as a Butterbase function with `trigger: { type: "http", config: { method: "POST", auth: "none" } }`.
export async function handler(req: Request, ctx: any): Promise<Response> {
const event = req.headers.get('x-bb-event');
const body = await req.text();
const payload = JSON.parse(body);
const botId: string = payload.data?.bot_id ?? payload.data?.id;
// Idempotency: skip if we already processed this bot + event combo.
const claimed = await ctx.idempotency.claim(`meeting:${botId}:${event}`);
if (!claimed) {
return new Response('duplicate', { status: 200 });
}
switch (event) {
case 'bot.done': {
// Artifacts are ready — store a reference or kick off extraction.
await ctx.db.query(
`UPDATE meeting_jobs SET status = 'done', bot_id = $1 WHERE external_ref = $2`,
[botId, payload.data?.metadata?.jobRef ?? botId]
);
break;
}
case 'transcript.done': {
// Transcript artifact URL is now available. Kick off downstream processing.
await ctx.db.query(
`INSERT INTO transcript_queue (bot_id, created_at) VALUES ($1, now())`,
[botId]
);
break;
}
case 'bot.fatal': {
await ctx.db.query(
`UPDATE meeting_jobs SET status = 'fatal' WHERE bot_id = $1`,
[botId]
);
break;
}
default:
// Other events (bot.in_call_recording, recording.done, transcript.failed) — handle as needed.
break;
}
return new Response('ok', { status: 200 });
}Key points:
---
Before dispatching a bot in a user-pays context, call `estimateCost` and surface the projected charge:
const { data: estimate } = await bb.ai.meetings.estimateCost({
durationMinutes: 60,
transcript: true,
});
// estimate.usd — show this to the user or check against a quota**Rates (v1):**
| Dimension | Rate | |-----------|------| | Recording (mp4 or audio_only) | **$0.50/hr + markup**, prorated per second | | Transcription | **$0.15/hr + markup**, prorated per second |
Both charges are applied against the app's AI credit balance once the bot reaches `done`.
For user-pays apps, hold a projected credit reservation at bot-start time and display a live cost counter using the bot's current duration (polled from `bb.ai.meetings.get`).
---
The underlying meetings infrastructure may change providers without notice. Do not depend on undocumented fields in the event payload or on provider-specific bot behavior.
---
Claude Code plugin for Butterbase — the AI-Native Backend-as-a-Service. This plugin gives Claude deep knowledge of Butterbase's nearly 40 MCP tools, guides you through common workflows, and auto-configures the MCP server connection.
Use when designing, deploying, or debugging a Butterbase Agent (declarative LLM/tool graph), registering an MCP server for tool…
Use when calling the app's AI gateway from agent tools — chat completions, embeddings, listing models, configuring defaults or…
Use when configuring OAuth providers (Google/GitHub/Apple/X/etc.), setting up post-login auth hooks, tuning JWT lifetimes, or…
Use when building a new Butterbase app from scratch, creating a full-stack application, or when the user asks to set up a…
Use when contributing to the Butterbase codebase, adding new MCP tools, creating API routes, writing migrations, or understanding…
Use when users report access denied errors, see wrong data, RLS policies are not working, or when troubleshooting Row-Level…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.