Skip to content
Development
Skill

/contributing

Use when contributing to the Butterbase codebase, adding new MCP tools, creating API routes, writing migrations, or understanding the monorepo architecture

From plugin
butterbase-skills
53539 skills33 commands1 MCP

Claude Code

$ npx -y skills add butterbase-ai/butterbase-skills --skill contributing --agent claude-code

SKILL.md

contributing.SKILL.md
name: contributing
description: Use when contributing to the Butterbase codebase, adding new MCP tools, creating API routes, writing migrations, or understanding the monorepo architecture

1. Overview

Contributor guide for the Butterbase monorepo. Covers architecture, how to add MCP tools, API routes, database migrations, and coding conventions.

---

2. Monorepo Map

| Directory | Package | Purpose | |-----------|---------|---------| | `packages/cli` | `@butterbase/cli` (v0.1.3) | Published CLI tool (Commander.js). Commands: init, apps, schema, functions, storage, deploy, data, env, keys, realtime, status, open | | `packages/sdk` | `@butterbase/sdk` (v1.2.1) | Published TypeScript SDK. Modules: auth, storage, functions, AI, billing, realtime, admin | | `packages/shared` | `@butterbase/shared` | Internal shared types, constants, schema DSL, error types | | `packages/plugin` | `@butterbase/plugin` | Claude Code plugin (this package — skills for AI agents) | | `services/control-api` | `@butterbase/control-api` | Fastify API server — the brain. Routes, plugins, services. Port 4000 | | `services/mcp-server` | `@butterbase/mcp` | MCP server with capability-dependent tools (consolidated `manage_*` action-based tools + standalone ones like `init_app`, `deploy_function`, `select_rows`). Runs via stdio or HTTP (served by control-api at `/mcp`); hosted cloud may also register `manage_office` | | `services/deno-runtime` | — | Serverless function executor. Deno-based worker isolation. Port 7133 | | `services/cron-scheduler` | `@butterbase/cron-scheduler` | Cron job runner using node-cron + cron-parser | | `services/dashboard` | — | React management UI (Vite + Radix UI) | | `services/dashboard-api` | — | Dashboard backend proxy. Port 4100 | | `services/docs` | `@butterbase/docs` | Astro/Starlight documentation site | | `services/storage-indexer` | — | Cloudflare Worker for S3 event indexing | | `db/control-plane` | — | SQL migrations (sequential numbering, `001_` upward). Control plane database schema | | `db/data-plane` | — | Per-app database initialization scripts |

---

3. Adding a New MCP Tool (4 Steps)

Step 1: Create tool file at `services/mcp-server/src/tools/my-new-tool.ts`

Decide whether the new capability is a standalone tool (single, self-contained operation like `init_app`) or another action on an existing umbrella tool (`manage_schema`, `manage_function`, etc). Most new operations should be added as actions on an existing `manage_*` tool — this keeps the surface area small for AI agents.

For a brand-new standalone tool, follow the pattern from `init-app.ts`:

import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
import { apiPost } from '../api-client.js';

interface MyResponse {
  // response shape
}

export function registerMyNewTool(server: McpServer) {
  server.tool(
    'my_new_tool',      // snake_case name
    `Tool description.   // Multi-line description with examples

Example:
  Input: { ... }
  Output: { ... }

Common errors:
  - ERROR_CODE: Description`,
    {
      // Zod schema for parameters
      app_id: z.string().describe('The app ID'),
      param: z.string().describe('Parameter description'),
    },
    async ({ app_id, param }) => {
      const result = await apiPost<MyResponse>(`/v1/${app_id}/my-endpoint`, { param });
      return {
        content: [{
          type: 'text' as const,
          text: JSON.stringify(result, null, 2),
        }],
      };
    }
  );
}

API client functions available: `apiGet`, `apiPost`, `apiPatch`, `apiDelete` (from `../api-client.js`).

Step 2: Register in `services/mcp-server/src/create-server.ts`

import { registerMyNewTool } from './tools/my-new-tool.js';
// ...
registerMyNewTool(server);

Step 3: Create the backing API route in `services/control-api/src/routes/`

  • Fastify route handler matching the endpoint your tool calls
  • Register in `services/control-api/src/index.ts`

Step 4: Update documentation in `services/mcp-server/src/docs/user-documentation.ts`

  • Add tool to the relevant section's table in the `SECTIONS` object

---

4. Adding a Database Migration

  • **IMPORTANT**: Use `scripts/migrate.ts` or `scripts/backfill-migrations.ts`, NEVER raw `psql`
  • Migration files: `db/control-plane/NNN_description.sql` (sequential numbering, starting at `001_initial_schema.sql`)
  • Pick the next free three-digit prefix; never edit a committed migration
  • Run migrations: `npx tsx scripts/migrate.ts`

---

5. Coding Conventions

| Convention | Example | |-----------|---------| | MCP tool names | `snake_case`. Two flavours: standalone (`init_app`, `deploy_function`, `select_rows`) and `manage_*` umbrella tools that take an `action` enum (`manage_schema`, `manage_rls`, `manage_function`, `manage_frontend`, etc.) | | App IDs | `app_` prefix: `app_abc123` | | Service keys | `bb_sk_` prefix: `bb_sk_a1b2c3...` | | Environment variables | `BUTTERBASE_` prefix: `BUTTERBASE_API_KEY` | | Response metadata | `_meta.next_actions` (suggested next tool calls), `_meta.resource_info` (quota/state) | | Error codes | `UPPERCASE_WITH_UNDERSCORES`: `AUTH_RLS_POLICY_VIOLATION`, `QUOTA_TABLE_LIMIT` | | Domain | `butterbase.ai` (never "nira") |

---

6. Running Locally

docker-compose -f docker-compose.local.yml up

| Service | Port | URL | |---------|------|-----| | Control API | 4000 | `http://localhost:4000` | | Dashboard API | 4100 | `http://localhost:4100` | | Deno Runtime | 7133 | `http://localhost:7133` | | Control Plane DB | 5433 | `postgres://localhost:5433` | | Data Plane DB | 5435 | `postgres://localhost:5435` | | PgBouncer | 6432 | `postgres://localhost:6432` | | LocalStack (S3) | 4566 | `http://localhost:4566` |

---

7. Testing

  • Framework: Vitest
  • Run tests per workspace: `cd services/control-api && npm test`
  • Test files: `__tests__/` directory or co-located `*.test.ts`
  • Build all workspaces: `npm run b
Read more
@butterbase-ai
Ships withbutterbase-skills

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.

53539 skills1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
535
Star history of butterbase-ai/butterbase-skills on GitHub, a chart by star-history.com

Other skills on butterbase-skills.

agents

agents

Use when designing, deploying, or debugging a Butterbase Agent (declarative LLM/tool graph), registering an MCP server for tool…

ai

ai

Use when calling the app's AI gateway from agent tools — chat completions, embeddings, listing models, configuring defaults or…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills11d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc13d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react2d252k
@facebook@facebookInstall Skill

Questions about contributing.

Which coding agents can use contributing?
contributing installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.