name: supabase description: Complete guide for the Supabase plugin — Management API access for running SQL queries, listing projects, managing edge functions, secrets, migrations, and inspecting project health.
Supabase Plugin
This plugin provides access to the Supabase Management API on the user's behalf, using a stored Personal Access Token (PAT).
Capabilities:
- List and inspect Supabase projects
- Run arbitrary SQL against any project database
- Generate TypeScript types from the database schema
- List, create, and manage edge functions
- Manage project secrets
- List and apply database migrations
- Check project health and performance advisors
- Retrieve project API keys and configuration
Authentication
Request the stored Supabase credential. The accessToken field is an opaque placeholder — the sandbox fetch proxy substitutes the real value automatically. Never decode or transform it.
const cred = await API.getCredential('supabase-pat');
if (!cred) {
return 'Supabase credential is not configured. Ask the user to create a Personal Access Token at supabase.com/dashboard/account/tokens, then store it in Settings.';
}
Making Requests
All requests go to https://api.supabase.com/v1/. Always pass the token as a Bearer header:
async function sbGet(path) {
const res = await fetch(`https://api.supabase.com/v1${path}`, {
headers: {
Authorization: `Bearer ${cred.accessToken}`,
'Content-Type': 'application/json',
},
});
if (!res.ok) throw new Error(`Supabase API ${res.status}: ${await res.text()}`);
return res.json();
}
async function sbPost(path, body) {
const res = await fetch(`https://api.supabase.com/v1${path}`, {
method: 'POST',
headers: {
Authorization: `Bearer ${cred.accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
if (!res.ok) throw new Error(`Supabase API ${res.status}: ${await res.text()}`);
return res.json();
}
async function sbPatch(path, body) {
const res = await fetch(`https://api.supabase.com/v1${path}`, {
method: 'PATCH',
headers: {
Authorization: `Bearer ${cred.accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
if (!res.ok) throw new Error(`Supabase API ${res.status}: ${await res.text()}`);
return res.json();
}
async function sbDelete(path) {
const res = await fetch(`https://api.supabase.com/v1${path}`, {
method: 'DELETE',
headers: {
Authorization: `Bearer ${cred.accessToken}`,
'Content-Type': 'application/json',
},
});
if (!res.ok) throw new Error(`Supabase API ${res.status}: ${await res.text()}`);
if (res.status === 204) return null;
return res.json();
}
Identifying the Project
Most endpoints require a project ref — the unique identifier for a Supabase project (e.g. ypnrbornkuwxlvjkgubi). It appears in the project's dashboard URL:
https://supabase.com/dashboard/project/{ref}/...
If the user hasn't specified a project ref, list their projects first:
const projects = await sbGet('/projects');
return projects.map(p => ({ id: p.id, name: p.name, region: p.region }));
Then ask the user which project to target.
Key Endpoints
Projects
List all projects
GET /v1/projects
Returns all projects the PAT has access to, including id, name, region, and status.
Get a specific project
GET /v1/projects/{ref}
Returns full project details.
Get project health
GET /v1/projects/{ref}/health
Returns the current health status of the project.
Get project API keys
GET /v1/projects/{ref}/api-keys
Returns the project's API keys (anon, service_role, etc.).
Running SQL (The Primary Tool)
Execute a SQL query
POST /v1/projects/{ref}/database/query
Body: { "query": "SELECT * FROM public.users LIMIT 10" }
This is the most powerful endpoint — it runs arbitrary SQL against the project's Postgres database with full privileges.
Execute a read-only SQL query
POST /v1/projects/{ref}/database/query/read-only
Body: { "query": "SELECT ..." }
Same as above but restricted to read-only operations. Use this for SELECT queries to avoid accidental mutations.
Common SQL Patterns
List all tables in the public schema:
SELECT table_name, table_type
FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY table_name;
Describe a table's columns:
SELECT column_name, data_type, is_nullable, column_default
FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'your_table'
ORDER BY ordinal_position;
List all schemas:
SELECT schema_name
FROM information_schema.schemata
WHERE schema_name NOT IN ('pg_catalog', 'information_schema', 'pg_toast')
ORDER BY schema_name;
List foreign key relationships:
SELECT
tc.table_name,
kcu.column_name,
ccu.table_name AS foreign_table,
ccu.column_name AS foreign_column
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage ccu
ON tc.constraint_name = ccu.constraint_name
WHERE tc.constraint_type = 'FOREIGN KEY'
AND tc.table_schema = 'public';
List indexes on a table:
SELECT indexname, indexdef
FROM pg_indexes
WHERE tablename = 'your_table' AND schemaname = 'public';
List RLS policies:
SELECT tablename, policyname, permissive, roles, cmd, qual, with_check
FROM pg_policies
WHERE schemaname = 'public';
Count rows in a table:
SELECT count(*) FROM public.your_table;
Insert a row:
INSERT INTO public.your_table (col1, col2) VALUES ('val1', 'val2') RETURNING *;
Update rows:
UPDATE public.your_table SET col1 = 'new_val' WHERE id = 123 RETURNING *;
Delete rows:
DELETE FROM public.your_table WHERE id = 123 RETURNING *;
TypeScript Types
Generate TypeScript types from the database schema
GET /v1/projects/{ref}/types/typescript
Returns TypeScript type definitions matching the current database schema. Useful for keeping frontend types in sync.
Edge Functions
List edge functions
GET /v1/projects/{ref}/functions
Returns all deployed edge functions with their slugs, status, and metadata.
Get a specific edge function
GET /v1/projects/{ref}/functions/{function_slug}
Delete an edge function
DELETE /v1/projects/{ref}/functions/{function_slug}
Secrets
List project secrets
GET /v1/projects/{ref}/secrets
Returns secret names (values are redacted).
Create a secret
POST /v1/projects/{ref}/secrets
Body: { "name": "MY_SECRET", "value": "secret_value" }
Delete secrets
DELETE /v1/projects/{ref}/secrets
Body: ["SECRET_NAME_1", "SECRET_NAME_2"]
Database Migrations
List migrations
GET /v1/projects/{ref}/database/migrations
Create a migration
POST /v1/projects/{ref}/database/migrations
Body: { "name": "add_users_table", "statements": ["CREATE TABLE ..."] }
Configuration
Get PostgREST config
GET /v1/projects/{ref}/postgrest
Returns the PostgREST configuration (exposed schemas, max rows, etc.).
Update PostgREST config
PATCH /v1/projects/{ref}/postgrest
Body: { "max_rows": 1000 }
Get database Postgres config
GET /v1/projects/{ref}/config/database/postgres
Get disk utilization
GET /v1/projects/{ref}/config/disk/util
Advisors
Performance advisor
GET /v1/projects/{ref}/advisors/performance
Returns performance lints (unindexed foreign keys, unused indexes, etc.).
Security advisor
GET /v1/projects/{ref}/advisors/security
Returns security lints. Add ?lint_type=sql to filter.
Organizations
List organizations
GET /v1/organizations
Get organization details
GET /v1/organizations/{slug}
List organization members
GET /v1/organizations/{slug}/members
List organization projects
GET /v1/organizations/{slug}/projects
Common Patterns
Explore a project's database schema
const cred = await API.getCredential('supabase-pat');
const ref = 'YOUR_PROJECT_REF';
// List all tables
const tables = await sbPost(`/projects/${ref}/database/query/read-only`, {
query: `SELECT table_name, table_type FROM information_schema.tables WHERE table_schema = 'public' ORDER BY table_name`
});
return tables;
Query data from a table
const cred = await API.getCredential('supabase-pat');
const ref = 'YOUR_PROJECT_REF';
const result = await sbPost(`/projects/${ref}/database/query/read-only`, {
query: `SELECT * FROM public.users ORDER BY created_at DESC LIMIT 20`
});
return result;
Insert data
const cred = await API.getCredential('supabase-pat');
const ref = 'YOUR_PROJECT_REF';
const result = await sbPost(`/projects/${ref}/database/query`, {
query: `INSERT INTO public.todos (title, completed) VALUES ('Buy milk', false) RETURNING *`
});
return result;
Check project health and performance
const cred = await API.getCredential('supabase-pat');
const ref = 'YOUR_PROJECT_REF';
const health = await sbGet(`/projects/${ref}/health`);
const perf = await sbGet(`/projects/${ref}/advisors/performance`);
const disk = await sbGet(`/projects/${ref}/config/disk/util`);
return { health, performanceLints: perf.length, disk };
Generate and display TypeScript types
const cred = await API.getCredential('supabase-pat');
const ref = 'YOUR_PROJECT_REF';
const types = await sbGet(`/projects/${ref}/types/typescript`);
return types;
List edge functions and their status
const cred = await API.getCredential('supabase-pat');
const ref = 'YOUR_PROJECT_REF';
const functions = await sbGet(`/projects/${ref}/functions`);
return functions.map(f => ({
slug: f.slug,
name: f.name,
status: f.status,
version: f.version,
}));
Important Rules
- Always call
API.getCredential('supabase-pat')before any Supabase API call. If it returnsnull, prompt the user to configure it. - Always identify the target project ref before making project-specific calls. Either ask the user or call
GET /v1/projectsto list available projects. - Use
POST /v1/projects/{ref}/database/query/read-onlyfor SELECT queries to avoid accidental writes. - Use
POST /v1/projects/{ref}/database/queryfor INSERT/UPDATE/DELETE/DDL operations. - When running destructive SQL (DROP, DELETE, TRUNCATE), always confirm with the user first.
- Treat tokens as sensitive — never log or display them.
- The Management API does not have publicly documented rate limits, but be reasonable — avoid tight loops of requests.
- SQL query results may be large. Use
LIMITclauses to keep responses manageable.