Execute database operations via Supabase MCP (query/write/migration/logs/type generation). Triggers: query/statistics/export/insert/update/delete/fix/backfill/migrate/logs/alerts/type generation...
Interact with Supabase database via MCP tools, execute queries, writes, migrations, and diagnostics.
Applies to:
Does not apply to:
workflow-ship-faster (Step 6: Supabase integration) for project-side setup; this skill only handles DB-side actions and gatesCalled by:
workflow-ship-faster uses this skill as DB operation foundation; workflow-ship-faster handles project-side integration, this skill handles DB-side actions and security gatesShip Faster vendors Supabase's Postgres best practices inside the supabase skill (install supabase alongside this skill if you want these references available locally):
supabase/references/postgres-best-practices/AGENTS.mdsupabase/references/postgres-best-practices/rules/*.mdConsult it when:
When proposing changes, cite the relevant rule file path (for example: supabase/references/postgres-best-practices/rules/query-missing-indexes.md) and keep changes minimal.
When integrating database operations into multi-step workflows, persist all context and artifacts to disk, passing only paths between agents/sub-agents.
Recommended directory structure (within project): runs/<workflow>/active/<run_id>/
01-input/goal.md (requirements), 01-input/context.json (known tables/fields/IDs)03-plans/sql.md (SQL to execute; write operations must be written here before confirmation)05-final/result.md (conclusion + key numbers + SQL + truncated results)logs/events.jsonl (summary of each tool call; do not log sensitive field values)| Tool | Parameters | Purpose |
|---|---|---|
list_tables |
{"schemas":["public"]} |
List all tables in specified schema |
execute_sql |
{"query":"SELECT ..."} |
Execute SQL (query or DML) |
apply_migration |
{"name":"snake_case_name","query":"-- DDL"} |
Apply database migration |
list_migrations |
{} |
View existing migrations |
generate_typescript_types |
{} |
Generate TypeScript type definitions |
get_project_url |
{} |
Get project URL |
get_publishable_keys |
{} |
Get public API keys |
get_logs |
{"service":"postgres|api|auth|storage|realtime|edge-function|branch-action"} |
Query service logs |
get_advisors |
{"type":"security|performance"} |
Get security/performance recommendations |
Optional tools (if enabled):
list_edge_functions, get_edge_function, deploy_edge_functioncreate_branch, list_branches, merge_branch, reset_branch, rebase_branch, delete_branchLIMIT 50, unless user explicitly requests moreSELECT count(*) firstapply_migration, execute_sql cannot run DDL directly1. Parse requirements ā restate objective
2. Unsure about tables/fields ā first list_tables or execute_sql to query information_schema
3. Plan SQL ā present to user
4. Read-only ā execute directly
5. Write operation ā confirm before execution ā verify affected rows ā report result
Example output:
ā
Query complete: 142 new users in the last 7 days
Executed SQL:
SELECT DATE(created_at) as date, COUNT(*) as count
FROM user_profiles
WHERE created_at > NOW() - INTERVAL '7 days'
GROUP BY DATE(created_at) ORDER BY date DESC;
| date | count |
|------------|-------|
| 2025-01-09 | 23 |
| 2025-01-08 | 31 |
| ... | ... |
| Situation | Action |
|---|---|
| SQL syntax error | Return error summary + fix suggestions |
| Insufficient permissions | Explain required permissions + alternatives |
| No data returned | Explain possible reasons (conditions too strict? data doesn't exist?) |
| RLS blocked | Suggest checking RLS policy or using service_role |
User: Get registered user count for the last 7 days, by day
Execution:
1. Confirm table user_profiles, field created_at
2. Execute aggregation SQL
3. Return: conclusion + numbers + SQL + table
User: Find projects that have runs but all failed
Execution:
1. Confirm projects, runs tables and status field
2. Present JOIN + aggregation SQL
3. Execute and return results (mask email)
User: Create a new run for project xxx
Execution:
1. First check if project exists
2. Present INSERT SQL + expected impact: 1 row
3. Await confirmation ā execute ā return new record id
User: Change run abc's status to completed
Execution:
1. First SELECT to verify current state
2. Present UPDATE SQL + WHERE id = 'abc'
3. Confirm ā execute ā SELECT again to verify
User: Delete all runs where status = 'failed'
Execution:
1. First SELECT count(*) WHERE status = 'failed'
2. Present count + DELETE SQL
3. If > 100 rows, force double confirmation
4. After confirmation execute ā report deleted row count
User: Clear the runs table
Execution:
ā Refuse to execute
ā Prompt: DELETE without WHERE condition, this will delete all data
ā Suggest: Use TRUNCATE (requires migration) or add explicit condition
Get latest schema at runtime:
-- List all tables
SELECT table_name FROM information_schema.tables
WHERE table_schema = 'public';
-- View table structure
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_name = '<table_name>';
For project-specific schema (may be outdated), see schema.md. Default to information_schema / generate_typescript_types as source of truth.