Supabase
When to Use
Use when doing ANY task involving Supabase. Triggers include:
- Supabase products: Database, Auth, Edge Functions, Realtime, Storage, Vectors, Cron, Queues
- Client libraries and SSR integrations:
supabase-js, @supabase/ssr in Next.js, React, SvelteKit, Astro, Remix
- Auth issues: login, logout, sessions, JWT claims, OAuth, anonymous sign-ins, MFA
- Database work: migrations, RLS policies, views, functions, triggers, schema changes
- Supabase CLI: local development, db push/pull, migration management, advisors
- Supabase MCP Server:
execute_sql, search_docs, get_advisors, apply_migration
- Security review: RLS, API key exposure, storage policies,
SECURITY DEFINER functions
Do NOT use this skill for tasks unrelated to Supabase. If the user mentions Firebase, PlanetScale, Neon, or another database/auth provider, defer to the appropriate skill.
Prerequisites
- Supabase CLI installed and on PATH. Verify with
supabase --version. Minimum versions for certain commands:
supabase db query → CLI v2.79.0+
supabase db advisors → CLI v2.81.3+
- Supabase MCP Server configured (optional but preferred for SQL execution and doc search). See setup at
https://supabase.com/docs/guides/getting-started/mcp.
- Node.js / package manager if working with client libraries.
- Windows host (PowerShell) is the primary environment. Use PowerShell-compatible syntax for shell commands. On Windows, path separators in commands may need backslashes; the Supabase CLI itself accepts forward slashes in most contexts.
Procedure
1. Verify Against Current Docs Before Implementing
Supabase changes frequently. Do NOT rely on training data for function signatures, config.toml settings, or API conventions.
Fetch the changelog index:
curl -sL https://supabase.com/changelog.md
Scan for breaking-change tags relevant to your task. Follow linked pages for any that apply.
Look up the relevant topic using documentation access methods in priority order:
- MCP
search_docs tool (preferred — returns relevant snippets directly)
- Fetch docs pages as markdown — append
.md to any docs URL path (e.g., https://supabase.com/docs/guides/api/securing-your-api.md)
- Web search for Supabase-specific topics when you don't know which page to look at
2. Discover CLI Commands via --help
Always discover commands via --help — never guess. The CLI structure changes between versions.
supabase --help # All top-level commands
supabase <group> --help # Subcommands (e.g., supabase db --help)
supabase <group> <command> --help # Flags for a specific command
Check your version:
supabase --version
For CLI changelogs and version-specific features, consult the CLI documentation or GitHub releases.
3. Making Schema Changes
To make schema changes, use execute_sql (MCP) or supabase db query (CLI). These run SQL directly on the database without creating migration history entries, so you can iterate freely and generate a clean migration when ready.
HARD RULE: Do NOT use apply_migration to change a local database schema. It writes a migration history entry on every call, which means you can't iterate, and supabase db diff / supabase db pull will produce empty or conflicting diffs. If you use it, you'll be stuck with whatever SQL you passed on the first try.
4. Committing Schema Changes to a Migration File
When ready to commit your changes:
Run advisors:
supabase db advisors
Requires CLI v2.81.3+. Fallback: MCP get_advisors. Fix any issues found.
Review the Security Checklist (below) if your changes involve views, functions, triggers, or storage.
Generate the migration:
supabase db pull <descriptive-name> --local --yes
Verify:
supabase migration list --local
HARD RULE: When you need a new migration SQL file, always create it with supabase migration new <name> first. Never invent a migration filename or rely on memory for the expected format.
5. Exposing Tables to the Data API
Depending on the user's Data API settings, newly created tables may not be automatically exposed via the Data (REST) API. If this is the case, anon and authenticated roles will need to be explicitly granted access.
This is separate from RLS, which controls which rows are visible once a table is accessible, not whether the table is accessible at all.
When a user reports a SQL-created table is unexpectedly inaccessible:
- Check their Data API settings.
- Check whether roles have been granted access via explicit
GRANT SQL.
- When granting public (
anon/authenticated) access, always enable RLS too.
See Exposing a Table to the Data API for the full setup workflow.
6. Enabling RLS on Exposed Schemas
Enable RLS on every table in any exposed schema, which includes public by default. Tables in exposed schemas can be reachable through the Data API when the anon/authenticated roles have access.
For private schemas, prefer RLS as defense in depth. After enabling RLS, create policies that match the actual access model rather than defaulting every table to the same auth.uid() pattern.
7. Supabase MCP Server Troubleshooting
Follow these steps in order when MCP tools aren't visible or connection fails:
Check if the server is reachable:
curl -so /dev/null -w "%{http_code}" https://mcp.supabase.com/mcp
A 401 is expected (no token) and means the server is up. Timeout or "connection refused" means it may be down.
Check .mcp.json configuration:
Verify the project root has a valid .mcp.json with the correct server URL. If missing, create one pointing to https://mcp.supabase.com/mcp.
Authenticate the MCP server:
If the server is reachable and .mcp.json is correct but tools aren't visible, the user needs to authenticate. The Supabase MCP server uses OAuth 2.1 — tell the user to trigger the auth flow in their agent, complete it in the browser, and reload the session.
Security Checklist
When working on any Supabase task that touches auth, RLS, views, storage, or user data, run through this checklist. These are Supabase-specific security traps that silently create vulnerabilities:
Auth and Session Security
- Never use
user_metadata claims in JWT-based authorization decisions. In Supabase, raw_user_meta_data is user-editable and can appear in auth.jwt(), so it is unsafe for RLS policies or any other authorization logic. Store authorization data in raw_app_meta_data / app_metadata instead.
- Deleting a user does not invalidate existing access tokens. Sign out or revoke sessions first, keep JWT expiry short for sensitive apps, and for strict guarantees validate
session_id against auth.sessions on sensitive operations.
- If you use
app_metadata or auth.jwt() for authorization, remember JWT claims are not always fresh until the user's token is refreshed.
API Key and Client Exposure
- Never expose the
service_role or secret key in public clients. Prefer publishable keys for frontend code. Legacy anon keys are only for compatibility. In Next.js, any NEXT_PUBLIC_ env var is sent to the browser.
RLS, Views, and Privileged Database Code
- Views bypass RLS by default. In Postgres 15 and above, use
CREATE VIEW ... WITH (security_invoker = true). In older versions of Postgres, protect your views by revoking access from the anon and authenticated roles, or by putting them in an unexposed schema.
- UPDATE requires a SELECT policy. In Postgres RLS, an UPDATE needs to first SELECT the row. Without a SELECT policy, updates silently return 0 rows — no error, just no change.
auth.role() is deprecated — use the TO clause instead. Supabase has deprecated auth.role() in favour of specifying the target role directly on the policy with TO authenticated or TO anon. Beyond deprecation, auth.role() = 'authenticated' breaks silently when anonymous sign-ins are enabled, because anonymous users carry the authenticated Postgres role and pass the check regardless of whether the user is genuinely signed in.-- Deprecated (do not use)
create policy "example" on table_name for select
using ( auth.role() = 'authenticated' );
TO authenticated alone is authentication without authorization (BOLA / IDOR). Using TO authenticated only checks the role — it does not restrict which rows a user can access. The correct pattern combines TO authenticated with an ownership predicate in USING:create policy "example" on table_name for select
to authenticated
using ( (select auth.uid()) = user_id );
- UPDATE policies require both
USING and WITH CHECK. Without WITH CHECK, a user can reassign a row's user_id to another user:create policy "example" on table_name for update
to authenticated
using ( (select auth.uid()) = user_id )
with check ( (select auth.uid()) = user_id );
SECURITY DEFINER functions bypass RLS. A SECURITY DEFINER function runs with its creator's privileges — typically a role with bypassrls (e.g., postgres). Never add SECURITY DEFINER to resolve a permission error; it silently removes access control without fixing the underlying cause. Prefer SECURITY INVOKER.
SECURITY DEFINER functions in public are callable by all roles. Postgres grants EXECUTE to PUBLIC by default for every new function, so any SECURITY DEFINER function in public is a public API endpoint callable by anon and authenticated (which inherit from PUBLIC) without any additional grant. When SECURITY DEFINER is genuinely needed (e.g., bypassing RLS on an internal lookup table), keep the function in a non-exposed schema, always include an auth.uid() check in the function body, and run supabase db advisors after making changes.
Storage Access Control
- Storage upsert requires INSERT + SELECT + UPDATE. Granting only INSERT allows new uploads but file replacement (upsert) silently fails. You need all three.
Dependency and Supply-Chain Security
- Always pin package versions and commit lockfiles when installing Supabase packages (
supabase-js, @supabase/ssr, supabase-py, etc.). See the npm security guide for the full checklist.
For any security concern not covered above, fetch the Supabase product security index: https://supabase.com/docs/guides/security/product-security.md
Pitfalls
- Relying on training data for Supabase features. Function signatures,
config.toml settings, and API conventions change between versions. Always verify against the changelog and current docs first.
- Using
apply_migration for local schema iteration. This writes a migration history entry on every call, preventing clean diffs. Use execute_sql (MCP) or supabase db query (CLI) for iteration instead.
- Inventing migration filenames. Always use
supabase migration new <name> to create migration files. Never rely on memory for the expected format.
auth.role() deprecation. Using auth.role() = 'authenticated' breaks silently when anonymous sign-ins are enabled. Use the TO clause instead.
TO authenticated without USING predicate. This is authentication without authorization — any authenticated user can access any row (BOLA / IDOR).
- UPDATE policies missing
WITH CHECK. Without it, users can reassign rows to other users.
- Views bypassing RLS. Default views run as the view owner. Use
WITH (security_invoker = true) on Postgres 15+.
SECURITY DEFINER in public schema. Callable by all roles including anon. Move to a non-exposed schema and add auth.uid() checks.
- Using
user_metadata for authorization. raw_user_meta_data is user-editable. Use app_metadata instead.
- Deleting users without revoking sessions. Existing access tokens remain valid. Sign out or revoke sessions first.
- Storage upsert with only INSERT grant. Silently fails. Need INSERT + SELECT + UPDATE.
- Tables not exposed via Data API. New SQL-created tables may need explicit
GRANT plus RLS enabled. Check Data API settings.
- CLI version requirements.
supabase db query needs v2.79.0+, supabase db advisors needs v2.81.3+. Use MCP fallbacks if below these versions.
- Looping on the same failed approach. If an approach fails after 2-3 attempts, stop and reconsider. Try a different method, check documentation, inspect errors more carefully, and review relevant logs.
Verification
After implementing any fix or change, run a test to confirm the change works. A fix without verification is incomplete.
Verify schema changes are committed:
supabase migration list --local
Confirm your new migration appears in the list.
Run advisors to catch security issues:
supabase db advisors
Or via MCP: get_advisors. Fix any issues found before proceeding.
Test RLS policies with a real query:
- Use
execute_sql (MCP) or supabase db query (CLI) to run a query that exercises the policy.
- For RLS, test as both
anon/authenticated roles to confirm row-level access is correct.
Verify CLI version meets minimums:
supabase --version
Verify MCP server connectivity:
curl -so /dev/null -w "%{http_code}" https://mcp.supabase.com/mcp
Expected: 401 (server is up, no token provided).
Verify package versions are pinned:
Check package.json (or equivalent) for exact Supabase package versions and confirm lockfile is committed.
Reference Guides
- Skill Feedback →
references/skill-feedback.md
MUST read when the user reports that this skill gave incorrect guidance or is missing information. Load this file to understand how to collect and report feedback.
Limitations
- Use this skill only when the task clearly matches its upstream product or API scope.
- Verify commands, API behavior, pricing, quotas, credentials, and deployment effects against current official documentation before making changes.
- Do not treat generated examples as a substitute for environment-specific tests, security review, or user approval for destructive or costly actions.
- No live secrets should be committed or shared. Use
YOUR_KEY placeholders in all examples.
1---2name: supabase3description: Implements Supabase Database, Auth, Edge Functions, Realtime, Storage, RLS, CLI, and supabase-js/SSR clients. Use when the task involves Supabase products, migrations, JWT/RLS, or the Supabase MCP. Not for Firebase, PlanetScale, Neon, or claimable neon.new databases. Do not use apply_migration to iterate a local schema; run execute_sql or db query first.4license: MIT5---67# Supabase89## When to Use1011Use when doing ANY task involving Supabase. Triggers include:1213- **Supabase products**: Database, Auth, Edge Functions, Realtime, Storage, Vectors, Cron, Queues14- **Client libraries and SSR integrations**: `supabase-js`, `@supabase/ssr` in Next.js, React, SvelteKit, Astro, Remix15- **Auth issues**: login, logout, sessions, JWT claims, OAuth, anonymous sign-ins, MFA16- **Database work**: migrations, RLS policies, views, functions, triggers, schema changes17- **Supabase CLI**: local development, db push/pull, migration management, advisors18- **Supabase MCP Server**: `execute_sql`, `search_docs`, `get_advisors`, `apply_migration`19- **Security review**: RLS, API key exposure, storage policies, `SECURITY DEFINER` functions2021Do NOT use this skill for tasks unrelated to Supabase. If the user mentions Firebase, PlanetScale, Neon, or another database/auth provider, defer to the appropriate skill.2223## Prerequisites2425- **Supabase CLI** installed and on PATH. Verify with `supabase --version`. Minimum versions for certain commands:26 - `supabase db query` → **CLI v2.79.0+**27 - `supabase db advisors` → **CLI v2.81.3+**28- **Supabase MCP Server** configured (optional but preferred for SQL execution and doc search). See setup at `https://supabase.com/docs/guides/getting-started/mcp`.29- **Node.js / package manager** if working with client libraries.30- **Windows host (PowerShell)** is the primary environment. Use PowerShell-compatible syntax for shell commands. On Windows, path separators in commands may need backslashes; the Supabase CLI itself accepts forward slashes in most contexts.3132## Procedure3334### 1. Verify Against Current Docs Before Implementing3536Supabase changes frequently. Do NOT rely on training data for function signatures, `config.toml` settings, or API conventions.37381. Fetch the changelog index:39 ```40 curl -sL https://supabase.com/changelog.md41 ```42 Scan for `breaking-change` tags relevant to your task. Follow linked pages for any that apply.43442. Look up the relevant topic using documentation access methods **in priority order**:45 - **MCP `search_docs` tool** (preferred — returns relevant snippets directly)46 - **Fetch docs pages as markdown** — append `.md` to any docs URL path (e.g., `https://supabase.com/docs/guides/api/securing-your-api.md`)47 - **Web search** for Supabase-specific topics when you don't know which page to look at4849### 2. Discover CLI Commands via --help5051Always discover commands via `--help` — never guess. The CLI structure changes between versions.5253```bash54supabase --help # All top-level commands55supabase <group> --help # Subcommands (e.g., supabase db --help)56supabase <group> <command> --help # Flags for a specific command57```5859Check your version:60```bash61supabase --version62```6364For CLI changelogs and version-specific features, consult the [CLI documentation](https://supabase.com/docs/reference/cli/introduction) or [GitHub releases](https://github.com/supabase/cli/releases).6566### 3. Making Schema Changes6768**To make schema changes, use `execute_sql` (MCP) or `supabase db query` (CLI).** These run SQL directly on the database without creating migration history entries, so you can iterate freely and generate a clean migration when ready.6970> **HARD RULE**: Do NOT use `apply_migration` to change a local database schema. It writes a migration history entry on every call, which means you can't iterate, and `supabase db diff` / `supabase db pull` will produce empty or conflicting diffs. If you use it, you'll be stuck with whatever SQL you passed on the first try.7172### 4. Committing Schema Changes to a Migration File7374When ready to commit your changes:75761. **Run advisors**:77 ```bash78 supabase db advisors79 ```80 Requires CLI v2.81.3+. Fallback: MCP `get_advisors`. Fix any issues found.81822. **Review the Security Checklist** (below) if your changes involve views, functions, triggers, or storage.83843. **Generate the migration**:85 ```bash86 supabase db pull <descriptive-name> --local --yes87 ```88894. **Verify**:90 ```bash91 supabase migration list --local92 ```9394> **HARD RULE**: When you need a new migration SQL file, **always** create it with `supabase migration new <name>` first. Never invent a migration filename or rely on memory for the expected format.9596### 5. Exposing Tables to the Data API9798Depending on the user's [Data API settings](https://supabase.com/dashboard/project/_/integrations/data_api/settings), newly created tables may not be automatically exposed via the Data (REST) API. If this is the case, `anon` and `authenticated` roles will need to be explicitly granted access.99100> This is separate from RLS, which controls which _rows_ are visible once a table is accessible, not whether the table is accessible at all.101102When a user reports a SQL-created table is unexpectedly inaccessible:1031. Check their Data API settings.1042. Check whether roles have been granted access via explicit `GRANT` SQL.1053. When granting public (`anon`/`authenticated`) access, **always enable RLS too**.106107See [Exposing a Table to the Data API](https://supabase.com/docs/guides/api/securing-your-api.md) for the full setup workflow.108109### 6. Enabling RLS on Exposed Schemas110111Enable RLS on **every table** in any exposed schema, which includes `public` by default. Tables in exposed schemas can be reachable through the Data API when the `anon`/`authenticated` roles have access.112113For private schemas, prefer RLS as defense in depth. After enabling RLS, create policies that match the actual access model rather than defaulting every table to the same `auth.uid()` pattern.114115### 7. Supabase MCP Server Troubleshooting116117Follow these steps in order when MCP tools aren't visible or connection fails:1181191. **Check if the server is reachable:**120 ```bash121 curl -so /dev/null -w "%{http_code}" https://mcp.supabase.com/mcp122 ```123 A `401` is expected (no token) and means the server is up. Timeout or "connection refused" means it may be down.1241252. **Check `.mcp.json` configuration:**126 Verify the project root has a valid `.mcp.json` with the correct server URL. If missing, create one pointing to `https://mcp.supabase.com/mcp`.1271283. **Authenticate the MCP server:**129 If the server is reachable and `.mcp.json` is correct but tools aren't visible, the user needs to authenticate. The Supabase MCP server uses OAuth 2.1 — tell the user to trigger the auth flow in their agent, complete it in the browser, and reload the session.130131## Security Checklist132133When working on any Supabase task that touches auth, RLS, views, storage, or user data, run through this checklist. These are Supabase-specific security traps that silently create vulnerabilities:134135### Auth and Session Security136137- **Never use `user_metadata` claims in JWT-based authorization decisions.** In Supabase, `raw_user_meta_data` is user-editable and can appear in `auth.jwt()`, so it is unsafe for RLS policies or any other authorization logic. Store authorization data in `raw_app_meta_data` / `app_metadata` instead.138- **Deleting a user does not invalidate existing access tokens.** Sign out or revoke sessions first, keep JWT expiry short for sensitive apps, and for strict guarantees validate `session_id` against `auth.sessions` on sensitive operations.139- **If you use `app_metadata` or `auth.jwt()` for authorization, remember JWT claims are not always fresh until the user's token is refreshed.**140141### API Key and Client Exposure142143- **Never expose the `service_role` or secret key in public clients.** Prefer publishable keys for frontend code. Legacy `anon` keys are only for compatibility. In Next.js, any `NEXT_PUBLIC_` env var is sent to the browser.144145### RLS, Views, and Privileged Database Code146147- **Views bypass RLS by default.** In Postgres 15 and above, use `CREATE VIEW ... WITH (security_invoker = true)`. In older versions of Postgres, protect your views by revoking access from the `anon` and `authenticated` roles, or by putting them in an unexposed schema.148- **UPDATE requires a SELECT policy.** In Postgres RLS, an UPDATE needs to first SELECT the row. Without a SELECT policy, updates silently return 0 rows — no error, just no change.149- **`auth.role()` is deprecated — use the `TO` clause instead.** Supabase has deprecated `auth.role()` in favour of specifying the target role directly on the policy with `TO authenticated` or `TO anon`. Beyond deprecation, `auth.role() = 'authenticated'` breaks silently when anonymous sign-ins are enabled, because anonymous users carry the `authenticated` Postgres role and pass the check regardless of whether the user is genuinely signed in.150 ```sql151 -- Deprecated (do not use)152 create policy "example" on table_name for select153 using ( auth.role() = 'authenticated' );154 ```155- **`TO authenticated` alone is authentication without authorization (BOLA / IDOR).** Using `TO authenticated` only checks the role — it does not restrict which rows a user can access. The correct pattern combines `TO authenticated` with an ownership predicate in `USING`:156 ```sql157 create policy "example" on table_name for select158 to authenticated159 using ( (select auth.uid()) = user_id );160 ```161- **UPDATE policies require both `USING` and `WITH CHECK`.** Without `WITH CHECK`, a user can reassign a row's `user_id` to another user:162 ```sql163 create policy "example" on table_name for update164 to authenticated165 using ( (select auth.uid()) = user_id )166 with check ( (select auth.uid()) = user_id );167 ```168- **`SECURITY DEFINER` functions bypass RLS.** A `SECURITY DEFINER` function runs with its creator's privileges — typically a role with `bypassrls` (e.g., `postgres`). Never add `SECURITY DEFINER` to resolve a permission error; it silently removes access control without fixing the underlying cause. Prefer `SECURITY INVOKER`.169- **`SECURITY DEFINER` functions in `public` are callable by all roles.** Postgres grants `EXECUTE` to `PUBLIC` by default for every new function, so any `SECURITY DEFINER` function in `public` is a public API endpoint callable by `anon` and `authenticated` (which inherit from `PUBLIC`) without any additional grant. When `SECURITY DEFINER` is genuinely needed (e.g., bypassing RLS on an internal lookup table), keep the function in a non-exposed schema, always include an `auth.uid()` check in the function body, and run `supabase db advisors` after making changes.170171### Storage Access Control172173- **Storage upsert requires INSERT + SELECT + UPDATE.** Granting only INSERT allows new uploads but file replacement (upsert) silently fails. You need all three.174175### Dependency and Supply-Chain Security176177- **Always pin package versions and commit lockfiles** when installing Supabase packages (`supabase-js`, `@supabase/ssr`, `supabase-py`, etc.). See the [npm security guide](https://supabase.com/docs/guides/security/npm-security.md) for the full checklist.178179For any security concern not covered above, fetch the Supabase product security index: `https://supabase.com/docs/guides/security/product-security.md`180181## Pitfalls1821831. **Relying on training data for Supabase features.** Function signatures, `config.toml` settings, and API conventions change between versions. Always verify against the changelog and current docs first.1842. **Using `apply_migration` for local schema iteration.** This writes a migration history entry on every call, preventing clean diffs. Use `execute_sql` (MCP) or `supabase db query` (CLI) for iteration instead.1853. **Inventing migration filenames.** Always use `supabase migration new <name>` to create migration files. Never rely on memory for the expected format.1864. **`auth.role()` deprecation.** Using `auth.role() = 'authenticated'` breaks silently when anonymous sign-ins are enabled. Use the `TO` clause instead.1875. **`TO authenticated` without `USING` predicate.** This is authentication without authorization — any authenticated user can access any row (BOLA / IDOR).1886. **UPDATE policies missing `WITH CHECK`.** Without it, users can reassign rows to other users.1897. **Views bypassing RLS.** Default views run as the view owner. Use `WITH (security_invoker = true)` on Postgres 15+.1908. **`SECURITY DEFINER` in `public` schema.** Callable by all roles including `anon`. Move to a non-exposed schema and add `auth.uid()` checks.1919. **Using `user_metadata` for authorization.** `raw_user_meta_data` is user-editable. Use `app_metadata` instead.19210. **Deleting users without revoking sessions.** Existing access tokens remain valid. Sign out or revoke sessions first.19311. **Storage upsert with only INSERT grant.** Silently fails. Need INSERT + SELECT + UPDATE.19412. **Tables not exposed via Data API.** New SQL-created tables may need explicit `GRANT` plus RLS enabled. Check Data API settings.19513. **CLI version requirements.** `supabase db query` needs v2.79.0+, `supabase db advisors` needs v2.81.3+. Use MCP fallbacks if below these versions.19614. **Looping on the same failed approach.** If an approach fails after 2-3 attempts, stop and reconsider. Try a different method, check documentation, inspect errors more carefully, and review relevant logs.197198## Verification199200After implementing any fix or change, run a test to confirm the change works. A fix without verification is incomplete.2012021. **Verify schema changes are committed:**203 ```bash204 supabase migration list --local205 ```206 Confirm your new migration appears in the list.2072082. **Run advisors to catch security issues:**209 ```bash210 supabase db advisors211 ```212 Or via MCP: `get_advisors`. Fix any issues found before proceeding.2132143. **Test RLS policies with a real query:**215 - Use `execute_sql` (MCP) or `supabase db query` (CLI) to run a query that exercises the policy.216 - For RLS, test as both `anon`/`authenticated` roles to confirm row-level access is correct.2172184. **Verify CLI version meets minimums:**219 ```bash220 supabase --version221 ```2222235. **Verify MCP server connectivity:**224 ```bash225 curl -so /dev/null -w "%{http_code}" https://mcp.supabase.com/mcp226 ```227 Expected: `401` (server is up, no token provided).2282296. **Verify package versions are pinned:**230 Check `package.json` (or equivalent) for exact Supabase package versions and confirm lockfile is committed.231232## Reference Guides233234- **Skill Feedback** → `references/skill-feedback.md`235 **MUST read when** the user reports that this skill gave incorrect guidance or is missing information. Load this file to understand how to collect and report feedback.236237## Limitations238239- Use this skill only when the task clearly matches its upstream product or API scope.240- Verify commands, API behavior, pricing, quotas, credentials, and deployment effects against current official documentation before making changes.241- Do not treat generated examples as a substitute for environment-specific tests, security review, or user approval for destructive or costly actions.242- No live secrets should be committed or shared. Use `YOUR_KEY` placeholders in all examples.