Claude Code Plugins

Community-maintained marketplace

Feedback
0
0

Master Supabase CLI automation, auth configuration, edge functions, secrets management, MCP integration, and Management API for production deployments

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name supabase-automation
description Master Supabase CLI automation, auth configuration, edge functions, secrets management, MCP integration, and Management API for production deployments

Supabase Automation & Integration Expert

Complete automation toolkit for Supabase CLI, auth configuration, edge functions, secrets, MCP integration, and API management.

MCP Integration

Supabase MCP Server provides Model Context Protocol integration for:

  • Docs - Access Supabase documentation
  • Account - Manage account and projects
  • Database - Query and manage database
  • Debugging - Debug edge functions and queries
  • Development - Local development tools
  • Functions - Manage edge functions
  • Branching - Database branching (preview environments)
  • Storage - File storage management

MCP Connection URL:

https://mcp.supabase.com/mcp?project_ref=spdtwktxdalcfigzeqrz&features=docs%2Caccount%2Cdatabase%2Cdebugging%2Cdevelopment%2Cfunctions%2Cbranching%2Cstorage

Setup MCP Server:

# Add to Claude Desktop config (~/.config/claude/claude_desktop_config.json)
{
  "mcpServers": {
    "supabase": {
      "url": "https://mcp.supabase.com/mcp",
      "params": {
        "project_ref": "spdtwktxdalcfigzeqrz",
        "features": "docs,account,database,debugging,development,functions,branching,storage"
      },
      "env": {
        "SUPABASE_ACCESS_TOKEN": "${SUPABASE_ACCESS_TOKEN}",
        "SUPABASE_ANON_KEY": "${SUPABASE_ANON_KEY}",
        "SUPABASE_SERVICE_ROLE_KEY": "${SUPABASE_SERVICE_ROLE_KEY}"
      }
    }
  }
}

Core Capabilities

1. CLI Automation

  • Project initialization and configuration
  • Local development setup
  • Database migrations and seeding
  • Type generation for TypeScript
  • Database schema management
  • Automated deployments

2. Auth Configuration

  • Site URL and redirect URL management
  • OAuth provider setup (Google, GitHub, etc.)
  • Email/password authentication
  • Magic links and OTP
  • JWT configuration
  • Row Level Security (RLS) policies

3. Edge Functions

  • Function creation and deployment
  • Deno runtime configuration
  • Secrets injection
  • CORS configuration
  • Function invocation and testing
  • Local development server

4. Secrets Management

  • Environment variable management
  • Secret storage via Supabase CLI
  • Vault integration
  • Secret rotation
  • Secure credential handling

5. Management API

  • Project configuration via API
  • Database connection pooling
  • API key management
  • Usage monitoring
  • Automated backups
  • SSL configuration

Documentation References

Essential Reading:

Quick Start Examples

1. Initialize Local Development

# Initialize Supabase in project
supabase init

# Start local Supabase (Docker required)
supabase start

# Generate TypeScript types
supabase gen types typescript --local > types/supabase.ts

# View local dashboard
# Studio: http://localhost:54323
# API URL: http://localhost:54321

2. Configure Auth URLs

# Set site URL (production)
supabase secrets set SITE_URL=https://app.insightpulseai.net

# Add redirect URLs via Dashboard or Management API
curl -X POST 'https://api.supabase.com/v1/projects/{project-ref}/config' \
  -H "Authorization: Bearer ${SUPABASE_ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "auth": {
      "site_url": "https://app.insightpulseai.net",
      "redirect_urls": [
        "https://app.insightpulseai.net/auth/callback",
        "https://*.insightpulseai.net/auth/callback",
        "http://localhost:3000/auth/callback"
      ]
    }
  }'

3. Deploy Edge Functions

# Create new edge function
supabase functions new my-function

# Write function code
cat > supabase/functions/my-function/index.ts << 'EOF'
import { serve } from "https://deno.land/std@0.168.0/http/server.ts"
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'

serve(async (req) => {
  const supabase = createClient(
    Deno.env.get('SUPABASE_URL') ?? '',
    Deno.env.get('SUPABASE_ANON_KEY') ?? ''
  )

  // Your function logic here
  const { data, error } = await supabase.from('table').select('*')

  return new Response(
    JSON.stringify({ data, error }),
    { headers: { "Content-Type": "application/json" } }
  )
})
EOF

# Set secrets for edge function
supabase secrets set API_KEY=your_secret_key
supabase secrets set OPENAI_API_KEY=sk-...

# Deploy edge function
supabase functions deploy my-function

# Invoke function
curl -X POST 'https://{project-ref}.supabase.co/functions/v1/my-function' \
  -H "Authorization: Bearer ${SUPABASE_ANON_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"param": "value"}'

4. Database Migrations

# Create new migration
supabase migration new create_users_table

# Edit migration file
cat > supabase/migrations/20250101_create_users_table.sql << 'EOF'
-- Create users table with RLS
CREATE TABLE public.users (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  email TEXT UNIQUE NOT NULL,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Enable RLS
ALTER TABLE public.users ENABLE ROW LEVEL SECURITY;

-- Policy: Users can read their own data
CREATE POLICY "Users can view own data"
  ON public.users
  FOR SELECT
  USING (auth.uid() = id);

-- Grant permissions
GRANT SELECT, INSERT, UPDATE ON public.users TO authenticated;
EOF

# Apply migrations locally
supabase db reset

# Push to production
supabase db push

5. Secrets Management

# List all secrets
supabase secrets list

# Set secret
supabase secrets set DATABASE_URL=postgresql://...
supabase secrets set STRIPE_SECRET_KEY=sk_live_...
supabase secrets set OPENAI_API_KEY=sk-...

# Unset secret
supabase secrets unset OLD_SECRET

# Use secrets in edge functions
# Automatically available as Deno.env.get('SECRET_NAME')

6. Management API - Full Configuration

// supabase-management.ts
const SUPABASE_ACCESS_TOKEN = process.env.SUPABASE_ACCESS_TOKEN
const PROJECT_REF = 'your-project-ref'
const API_BASE = 'https://api.supabase.com/v1'

// Configure auth settings
async function configureAuth() {
  const response = await fetch(`${API_BASE}/projects/${PROJECT_REF}/config`, {
    method: 'PATCH',
    headers: {
      'Authorization': `Bearer ${SUPABASE_ACCESS_TOKEN}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      auth: {
        site_url: 'https://app.insightpulseai.net',
        redirect_urls: [
          'https://app.insightpulseai.net/auth/callback',
          'https://*.insightpulseai.net/auth/callback',
          'http://localhost:3000/auth/callback'
        ],
        external_google_enabled: true,
        external_github_enabled: true,
        jwt_exp: 3600,
        refresh_token_rotation_enabled: true,
        security_refresh_token_reuse_interval: 10
      }
    })
  })
  return response.json()
}

// Configure database pooling
async function configureDatabasePooling() {
  const response = await fetch(`${API_BASE}/projects/${PROJECT_REF}/database/pooling`, {
    method: 'PATCH',
    headers: {
      'Authorization': `Bearer ${SUPABASE_ACCESS_TOKEN}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      pool_mode: 'transaction',
      default_pool_size: 15,
      ignore_startup_parameters: 'extra_float_digits'
    })
  })
  return response.json()
}

Common Workflows

Workflow 1: New Project Setup

# 1. Initialize project
supabase init
supabase login

# 2. Link to remote project
supabase link --project-ref {project-ref}

# 3. Pull remote schema
supabase db pull

# 4. Generate types
supabase gen types typescript --linked > types/supabase.ts

# 5. Start local development
supabase start

Workflow 2: Deploy with CI/CD

# .github/workflows/deploy-supabase.yml
name: Deploy Supabase

on:
  push:
    branches: [main]
    paths:
      - 'supabase/**'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Supabase CLI
        uses: supabase/setup-cli@v1
        with:
          version: latest

      - name: Link Supabase project
        run: supabase link --project-ref ${{ secrets.SUPABASE_PROJECT_REF }}
        env:
          SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}

      - name: Push database migrations
        run: supabase db push

      - name: Deploy edge functions
        run: |
          supabase functions deploy --no-verify-jwt
        env:
          SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}

      - name: Set production secrets
        run: |
          supabase secrets set OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}
          supabase secrets set STRIPE_SECRET_KEY=${{ secrets.STRIPE_SECRET_KEY }}

Workflow 3: Auth Provider Setup

// Setup Google OAuth
// 1. Get credentials from Google Cloud Console
// 2. Configure in Supabase Dashboard or via API

const setupGoogleAuth = async () => {
  const response = await fetch(
    `https://api.supabase.com/v1/projects/${PROJECT_REF}/config`,
    {
      method: 'PATCH',
      headers: {
        'Authorization': `Bearer ${SUPABASE_ACCESS_TOKEN}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        auth: {
          external_google_enabled: true,
          external_google_client_id: 'your-google-client-id.apps.googleusercontent.com',
          external_google_secret: 'GOCSPX-...'
        }
      })
    }
  )
  return response.json()
}

// Use in your app
const { data, error } = await supabase.auth.signInWithOAuth({
  provider: 'google',
  options: {
    redirectTo: 'https://app.insightpulseai.net/auth/callback'
  }
})

MCP-Powered Workflows

MCP Workflow 1: Database Branching for Testing

# Using MCP to create database branch for feature testing
# MCP command: create_database_branch

# Create branch from production
supabase branches create feature-trial-balance --project-ref spdtwktxdalcfigzeqrz

# Get branch connection string
supabase branches get feature-trial-balance --project-ref spdtwktxdalcfigzeqrz

# Run migrations on branch
supabase db push --branch feature-trial-balance

# Test your changes
# Connect app to branch URL temporarily

# Merge branch when ready
supabase branches merge feature-trial-balance --project-ref spdtwktxdalcfigzeqrz

MCP Workflow 2: Edge Function Debugging

// Use MCP debugging features to troubleshoot edge functions

// Enable verbose logging in edge function
import { serve } from "https://deno.land/std@0.168.0/http/server.ts"

serve(async (req) => {
  console.log('[DEBUG] Request received:', {
    method: req.method,
    url: req.url,
    headers: Object.fromEntries(req.headers)
  })

  try {
    // Your function logic
    const result = await processRequest(req)
    console.log('[DEBUG] Processing successful:', result)
    return new Response(JSON.stringify(result))
  } catch (error) {
    console.error('[ERROR] Function failed:', error)
    return new Response(JSON.stringify({ error: error.message }), {
      status: 500
    })
  }
})

// Check logs via MCP or CLI
// supabase functions logs my-function --project-ref spdtwktxdalcfigzeqrz

MCP Workflow 3: Storage Management

// Using MCP storage features for BIR document management

import { createClient } from '@supabase/supabase-js'

const supabase = createClient(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_ROLE_KEY!
)

// Create storage bucket for BIR forms
const { data: bucket, error: bucketError } = await supabase
  .storage
  .createBucket('bir-forms', {
    public: false,
    fileSizeLimit: 52428800, // 50MB
    allowedMimeTypes: ['application/pdf', 'image/png', 'image/jpeg']
  })

// Upload BIR form with RLS
const { data, error } = await supabase
  .storage
  .from('bir-forms')
  .upload(
    `company_${companyId}/1601C_${period}.pdf`,
    fileBuffer,
    {
      contentType: 'application/pdf',
      upsert: true,
      metadata: {
        company_id: companyId,
        form_type: '1601C',
        period: period
      }
    }
  )

// Create RLS policy for storage
/*
CREATE POLICY "Company users can access their BIR forms"
ON storage.objects FOR ALL
USING (
  bucket_id = 'bir-forms'
  AND (storage.foldername(name))[1] = 'company_' || auth.jwt() ->> 'company_id'
);
*/

InsightPulse Integration Patterns

Pattern 1: Odoo + Supabase Auth

// Edge function for Odoo SSO
import { serve } from "https://deno.land/std@0.168.0/http/server.ts"
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'

serve(async (req) => {
  const supabase = createClient(
    Deno.env.get('SUPABASE_URL') ?? '',
    Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
  )

  // Verify Supabase JWT
  const token = req.headers.get('Authorization')?.replace('Bearer ', '')
  const { data: { user }, error } = await supabase.auth.getUser(token)

  if (error || !user) {
    return new Response('Unauthorized', { status: 401 })
  }

  // Connect to Odoo
  const odooResponse = await fetch(`${Deno.env.get('ODOO_URL')}/web/session/authenticate`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      params: {
        db: Deno.env.get('ODOO_DB'),
        login: user.email,
        password: Deno.env.get('ODOO_SSO_PASSWORD')
      }
    })
  })

  return new Response(JSON.stringify(await odooResponse.json()), {
    headers: { 'Content-Type': 'application/json' }
  })
})

Pattern 2: Real-time Finance Updates

// Subscribe to trial balance changes
const subscription = supabase
  .channel('trial-balance-changes')
  .on(
    'postgres_changes',
    {
      event: '*',
      schema: 'public',
      table: 'account_move_line',
      filter: 'company_id=eq.1'
    },
    (payload) => {
      console.log('Change detected:', payload)
      // Update Superset dashboard
      // Trigger recalculation
    }
  )
  .subscribe()

Pattern 3: Vector Search for BIR Forms

-- Create vector extension
CREATE EXTENSION IF NOT EXISTS vector;

-- Add vector column for OCR embeddings
ALTER TABLE bir_forms
ADD COLUMN embedding vector(1536);

-- Create vector index
CREATE INDEX ON bir_forms
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);

-- Search similar forms
SELECT
  form_number,
  form_type,
  1 - (embedding <=> $1::vector) AS similarity
FROM bir_forms
ORDER BY embedding <=> $1::vector
LIMIT 10;

Environment Configuration

Local Development (.env.local)

# Supabase Local
NEXT_PUBLIC_SUPABASE_URL=http://localhost:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

# Local Postgres
DATABASE_URL=postgresql://postgres:postgres@localhost:54322/postgres

Production (.env.production)

# Supabase Production
NEXT_PUBLIC_SUPABASE_URL=https://spdtwktxdalcfigzeqrz.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

# Production Postgres (Pooler)
DATABASE_URL=postgresql://postgres.spdtwktxdalcfigzeqrz:password@aws-1-us-east-1.pooler.supabase.com:6543/postgres?sslmode=require

# Management API
SUPABASE_ACCESS_TOKEN=sbp_...
SUPABASE_PROJECT_REF=spdtwktxdalcfigzeqrz

Security Best Practices

1. Row Level Security (RLS)

-- Enable RLS on all tables
ALTER TABLE account_move_line ENABLE ROW LEVEL SECURITY;

-- Policy: Users can only see their company's data
CREATE POLICY "company_isolation"
  ON account_move_line
  FOR ALL
  USING (
    company_id IN (
      SELECT company_id
      FROM user_companies
      WHERE user_id = auth.uid()
    )
  );

2. Service Role Key Protection

  • Never expose service role key in client code
  • Use edge functions for privileged operations
  • Rotate keys regularly via Dashboard

3. OAuth Configuration

# Set redirect URLs to prevent open redirects
# Use wildcards carefully: https://*.insightpulseai.net is safer than https://*

Troubleshooting

Issue: Edge function deployment fails

# Check function logs
supabase functions logs my-function

# Test locally first
supabase functions serve my-function

# Verify Deno permissions
deno run --allow-net --allow-env index.ts

Issue: Auth redirect not working

# Verify redirect URLs in dashboard
# Check site URL matches your domain
# Ensure CORS is configured

# Test auth flow
curl -X POST 'https://{project-ref}.supabase.co/auth/v1/token?grant_type=password' \
  -H "apikey: ${SUPABASE_ANON_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"email": "test@example.com", "password": "password"}'

Issue: Database migration conflict

# Reset local database
supabase db reset

# Force push (DANGER: production)
supabase db push --force

# Create repair migration
supabase migration new repair_conflict

CLI Command Reference

# Project Management
supabase init                          # Initialize new project
supabase login                         # Login to Supabase
supabase projects list                 # List all projects
supabase link --project-ref {ref}      # Link to remote project

# Database
supabase db reset                      # Reset local database
supabase db push                       # Push migrations to remote
supabase db pull                       # Pull remote schema
supabase db diff                       # Show schema differences
supabase migration new {name}          # Create new migration
supabase migration up                  # Apply migrations

# Edge Functions
supabase functions new {name}          # Create new function
supabase functions deploy {name}       # Deploy function
supabase functions serve {name}        # Run function locally
supabase functions delete {name}       # Delete function

# Secrets
supabase secrets list                  # List all secrets
supabase secrets set {KEY}={VALUE}     # Set secret
supabase secrets unset {KEY}           # Remove secret

# Type Generation
supabase gen types typescript --local              # Generate from local
supabase gen types typescript --linked             # Generate from remote
supabase gen types typescript --db-url {URL}       # Generate from URL

# Local Development
supabase start                         # Start local Supabase
supabase stop                          # Stop local Supabase
supabase status                        # Show local status

Supabase UI Components (shadcn/ui)

Supabase provides official UI components built on shadcn/ui for Next.js and React apps.

Installation

# Install shadcn/ui first
npx shadcn@latest init

# Add Supabase UI components
npx shadcn@latest add https://ui.supabase.com/registry/supabase-auth-block.json
npx shadcn@latest add https://ui.supabase.com/registry/supabase-storage-upload.json
npx shadcn@latest add https://ui.supabase.com/registry/supabase-realtime-chat.json

Available Components

1. SupabaseAuthBlock

Complete authentication UI with sign-up, sign-in, password reset, and OAuth.

import { SupabaseAuthBlock } from '@/components/supabase-ui/auth-block'

export default function LoginPage() {
  return (
    <SupabaseAuthBlock
      providers={['google', 'github']}
      redirectTo="/dashboard"
      appearance={{
        theme: 'default',
        variables: {
          default: {
            colors: {
              brand: '#3b82f6',
              brandAccent: '#2563eb'
            }
          }
        }
      }}
    />
  )
}

2. SupabaseStorageUpload

File upload component with progress tracking and thumbnail previews.

import { SupabaseStorageUpload } from '@/components/supabase-ui/storage-upload'

export function FileUploader() {
  return (
    <SupabaseStorageUpload
      bucket="avatars"
      path={`${userId}/`}
      accept="image/*"
      maxSize={5242880} // 5MB
      onUpload={(url) => console.log('Uploaded:', url)}
    />
  )
}

3. SupabaseRealtimeChat

Real-time chat component with presence and typing indicators.

import { SupabaseRealtimeChat } from '@/components/supabase-ui/realtime-chat'

export function ChatRoom({ roomId }: { roomId: string }) {
  return (
    <SupabaseRealtimeChat
      channel={`room:${roomId}`}
      onMessage={(message) => console.log(message)}
    />
  )
}

Hybrid Stack: Next.js + OWL

For InsightPulse, we use both Supabase UI (Next.js) and Odoo OWL:

Use Next.js + Supabase UI for:

  • Public portals and customer-facing apps
  • Analytics dashboards (read-heavy)
  • Real-time features (chat, notifications)
  • File uploads and storage
  • Authentication and user management

Use Odoo OWL for:

  • ERP workflows (accounting, inventory, HR)
  • Complex business logic
  • BIR tax forms and compliance
  • Multi-company/multi-currency
  • Backend admin interfaces

See: /docs/HYBRID_STACK_ARCHITECTURE.md for complete integration guide.

When to Use This Skill

Use this skill when you need to:

  • ✅ Set up local Supabase development environment
  • ✅ Configure authentication providers and redirect URLs
  • ✅ Deploy and manage edge functions
  • ✅ Manage secrets and environment variables
  • ✅ Automate database migrations
  • ✅ Integrate Supabase with Odoo/Superset
  • ✅ Configure RLS policies
  • ✅ Use Management API for infrastructure automation
  • ✅ Set up CI/CD for Supabase deployments
  • ✅ Implement vector search with pgvector
  • ✅ Configure production database pooling
  • ✅ Build Next.js apps with Supabase UI components
  • ✅ Create hybrid Next.js + OWL architectures

Related Skills

  • supabase-rpc-manager - For RPC calls and real-time subscriptions
  • odoo - For Odoo ERP integration
  • superset-dashboard-automation - For analytics integration

Related Documentation

  • /docs/HYBRID_STACK_ARCHITECTURE.md - Next.js + OWL integration guide

Support Resources