supabase-skill について
supabase-skillは、Supabaseを使う開発者向けに、MCPの設定とデータベース設計・セキュリティ・運用を案内するスキルです。移行の指針や本番向けパターンも例とともに扱います。
主な機能
- 01Supabase MCPの設定とトラブルシューティング
- 02スキーマとリレーションの設計
- 03RLS・認証・RBACのガイダンス
- 04移行とブランチのパターン
- 05パフォーマンスと本番向けの例
活用シーン
- 01プロジェクト限定または読み取り専用接続の設定
- 02RLSを使うマルチテナント設計
- 03互換性を保つスキーマ移行の計画
- 04クエリ性能の調査
MCP 対応
Cursor、Claude Desktop、Claude Code CLI向けにSupabase MCPサーバーの設定と問題解決を案内します。クエリ、スキーマ確認、移行、プロジェクト設定のMCPツールも説明します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ tdimino/ claude-code-minoan --skill supabase-skillインストール後、Claude Code で/supabase-skillを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdassets/examples/memory-store.tsrls-policies.sqlsession-management.tssupabase-client.tsreferences/database-patterns.mdmcp-setup.mdproduction-patterns.mdschema-design.mdsecurity.mdtools-reference.mdreferences/github/CHANGELOG.mdfile_structure.mdissues.mdREADME.mdreleases.mdreferences/official-docs/migrations.mdrow-level-security.md詳細
Supabase MCP スキル
概要
このスキルでは、Model Context Protocol(MCP)を通じて Supabase を扱うための包括的なガイダンスを提供します。AI を活用したデータベース操作、最新のスキーマ設計、本番環境に対応したデータベースアーキテクチャを実現できます。
このスキルを使用する場面
以下のいずれかに該当する場合は、このスキルを使用してください。
セットアップと設定
- Supabase MCP サーバー(Cursor、Claude Desktop、Claude Code CLI)のセットアップまたは設定
- AI ツールと Supabase プロジェクトの接続
- MCP 接続の問題のデバッグ
- 読み取り専用モード、プロジェクトのスコープ設定、機能グループの設定
データベース設計
- ベストプラクティスに沿ったデータベーススキーマの設計
- テーブル間のリレーション(1 対多、多対多、ポリモーフィック)の実装
- 正規化パターン(単一テーブルとクラスごとのテーブルによる継承)の選択
- マルチテナントまたはマイクロサービス向けの設計
- 時系列データや監査ログの取り扱い
セキュリティとアクセス制御
- Row Level Security(RLS)ポリシーの実装
auth.usersを使用した認証連携の設定- ロールベースのアクセス制御(RBAC)の構築
- マルチテナントアプリケーションの保護
- 不正なデータアクセスの防止
マイグレーションとスキーマの進化
- データベースマイグレーションの作成と管理
- 互換性を損なわないスキーマの進化
- 後方互換性への対応
- テストでの Supabase ブランチの使用
本番環境のパターン
- タイムアウトロジックを用いたセッション管理
- メモリ永続化パターン(ソウルメモリとプロセスメモリによる二重永続化)
- リージョン別に整理したメッセージ保存
- 検証機能を備えた状態管理
- エラー処理とグレースフルデグラデーション
パフォーマンスと最適化
- クエリパフォーマンス向上のためのインデックス戦略
- EXPLAIN ANALYZE によるクエリ最適化
- コネクションプーリングの設定
- スケーリングのための読み取りレプリカのセットアップ
クイックリファレンスの例
1. MCP サーバーのセットアップ(Claude Code CLI)
# Basic installation with project scoping
claude mcp add --transport stdio \
--env SUPABASE_ACCESS_TOKEN=your_personal_access_token \
--scope local \
supabase -- npx -y @supabase/mcp-server-supabase@latest \
--project-ref=your_project_ref
# With read-only mode (safe for exploration)
claude mcp add --transport stdio \
--env SUPABASE_ACCESS_TOKEN=your_token \
--scope local \
supabase -- npx -y @supabase/mcp-server-supabase@latest \
--project-ref=your_project_ref \
--read-only
2. Supabase クライアントのシングルトン(TypeScript)
import { createClient, SupabaseClient } from '@supabase/supabase-js';
let supabaseClient: SupabaseClient | null = null;
export function getSupabaseClient(): SupabaseClient {
if (!supabaseClient) {
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY;
if (!supabaseUrl || !supabaseServiceKey) {
throw new Error('Missing Supabase environment variables');
}
supabaseClient = createClient(supabaseUrl, supabaseServiceKey, {
auth: {
autoRefreshToken: false, // Server-side: no refresh needed
persistSession: false, // Server-side: no persistence
},
});
}
return supabaseClient;
}
3. RLS を使用したユーザープロフィール(SQL)
-- Create profiles table linked to auth.users
create table public.profiles (
id uuid references auth.users(id) primary key,
username text unique not null,
full_name text,
avatar_url text,
created_at timestamptz default now()
);
-- Enable RLS
alter table public.profiles enable row level security;
-- Allow anyone to view profiles
create policy "Users can view all profiles"
on public.profiles for select
using (true);
-- Users can only update their own profile
create policy "Users can update own profile"
on public.profiles for update
using (auth.uid() = id);
4. RLS を使用したマルチテナント組織
-- Organizations table
create table public.organizations (
id uuid primary key default gen_random_uuid(),
name text not null,
slug text unique not null
);
-- Organization members junction table
create table public.org_members (
org_id uuid references public.organizations(id) on delete cascade,
user_id uuid references auth.users(id) on delete cascade,
role text not null check (role in ('owner', 'admin', 'member')),
primary key (org_id, user_id)
);
-- RLS: Users can only see organizations they're members of
alter table public.organizations enable row level security;
create policy "Users can view own organizations"
on public.organizations for select
using (
exists (
select 1 from public.org_members
where org_members.org_id = organizations.id
and org_members.user_id = auth.uid()
)
);
5. セッションの読み込みまたは作成パターン
// Load existing session or create new one
const { data: existing, error: fetchError } = await supabase
.from('user_sessions')
.select('*')
.eq('phone_number', phoneNumber)
.single();
// Handle "no rows returned" as valid (not an error)
if (fetchError && fetchError.code !== 'PGRST116') {
throw new Error(`Failed to load session: ${fetchError.message}`);
}
if (existing) {
// Update existing session
await supabase
.from('user_sessions')
.update({ last_active_at: new Date().toISOString() })
.eq('id', existing.id);
return existing;
}
// Create new session if none exists
const { data: newSession } = await supabase
.from('user_sessions')
.insert({ phone_number: phoneNumber })
.select()
.single();
return newSession;
6. キーと値のストレージ向け Upsert パターン
// Save or update soul memory (upsert pattern)
const { data, error } = await supabase
.from('soul_memories')
.upsert(
{
session_id: sessionId,
key: 'user_name',
value: { firstName: 'Alice', lastName: 'Smith' },
updated_at: new Date().toISOString(),
},
{ onConflict: 'session_id,key' } // Composite unique constraint
)
.select()
.single();
7. 時系列データパターン(履歴の追跡)
-- Products with full history tracking
create table public.products_history (
id uuid not null,
name text not null,
price numeric(10,2) not null,
-- Temporal columns
valid_from timestamptz not null default now(),
valid_to timestamptz, -- null = current version
-- Audit columns
changed_by uuid references auth.users(id),
change_reason text,
primary key (id, valid_from)
);
-- View for current products only
create view public.products as
select id, name, price
from public.products_history
where valid_to is null;
8. 分析用のマテリアライズドビュー
-- Aggregate analytics data for fast queries
create materialized view public.orders_analytics as
select
date_trunc('day', created_at) as order_date,
count(*) as total_orders,
sum(total) as revenue,
avg(total) as avg_order_value
from public.orders
where status = 'completed'
group by date_trunc('day', created_at);
-- Refresh function
create or replace function refresh_analytics()
returns void as $$
begin
refresh materialized view public.orders_analytics;
end;
$$ language plpgsql;
9. トリガーを使用した監査ログ
-- Audit logs table
create table public.audit_logs (
id bigint generated always as identity primary key,
table_name text not null,
record_id uuid not null,
action text not null check (action in ('insert', 'update', 'delete')),
old_data jsonb,
new_data jsonb,
user_id uuid references auth.users(id),
created_at timestamptz default now()
);
-- Trigger function for automatic auditing
create or replace function public.audit_trigger()
returns trigger as $$
begin
insert into public.audit_logs (
table_name, record_id, action, old_data, new_data, user_id
) values (
TG_TABLE_NAME,
coalesce(NEW.id, OLD.id),
lower(TG_OP),
to_jsonb(OLD),
to_jsonb(NEW),
auth.uid()
);
return NEW;
end;
$$ language plpgsql security definer;
10. pg_notify を使用したイベント駆動パターン
-- Publish events using PostgreSQL NOTIFY
create or replace function orders_service.notify_order_created()
returns trigger as $$
begin
perform pg_notify(
'order_created',
json_build_object(
'order_id', NEW.id,
'user_id', NEW.user_id,
'total', NEW.total
)::text
);
return NEW;
end;
$$ language plpgsql;
create trigger order_created_trigger
after insert on orders_service.orders
for each row execute function orders_service.notify_order_created();
主要な概念
Row Level Security(RLS)
ポリシーに基づいて、ユーザーがアクセスできる行を制限する PostgreSQL の機能です。マルチテナントアプリケーションやユーザーデータの分離に不可欠です。
MCP(Model Context Protocol)
AI アシスタントが Supabase などの外部サービスとやり取りできるようにするプロトコルです。自然言語によるクエリやスキーマ操作を可能にします。Supabase MCP サーバーは、Edge Functions 上の mcp-lite(コールドスタートなし、グローバルデプロイ)およびセルフホスト可能な Docker イメージ(supabase/mcp-server:latest)としても利用できます。
Upsert パターン
onConflict を使用し、新しい行を挿入するか、行がすでに存在する場合は更新します。競合状態を防ぐアトミックな操作です。
複合キー
複数のカラムにまたがる一意制約です(例:session_id,key)。コンテキスト内でのデータのスコープ設定に使用します。
JSONB ストレージ
PostgreSQL のバイナリ JSON ストレージ形式です。クエリパフォーマンスを維持しながら、柔軟なスキーマを使用できます。
時系列データ
valid_from と valid_to のタイムスタンプを使用して、過去の変更を追跡します。特定時点のクエリが可能になります。
Service Role と Anon Key
- Service Role:管理者アクセス。RLS をバイパスします(サーバー側でのみ使用してください)
- Anon Key:ユーザーアクセス。RLS の対象です(クライアント側で安全に使用できます)
参照ファイル
コアリファレンス
references/mcp-setup.md - MCP サーバーの設定
Supabase MCP サーバーのセットアップに関する完全ガイド:
- リモート(ホスト型)とローカル(セルフホスト型)のインストール
- Cursor、Claude Desktop、Claude Code CLI の設定
- OAuth と Personal Access Tokens による認証
- セキュリティのベストプラクティス(読み取り専用モード、プロジェクトのスコープ設定)
- 接続と認証の問題のトラブルシューティング
references/database-patterns.md - モダンなデータベース設計
スケーラブルなアプリケーションのためのアーキテクチャパターン:
- データレイクハウスパターン(1 つのシステムで OLTP + OLAP)
- マイクロサービスパターン(サービスごとにデータベースを分離)
- イベントソーシングパターン(完全な監査証跡)
- CQRS パターン(読み取りモデルと書き込みモデルの分離)
- 継承パターン(単一テーブルとクラスごとのテーブル)
- ポリモーフィック関連付け
- 時系列データパターン(SCD Type 2)
references/schema-design.md - PostgreSQL のベストプラクティス
堅牢なスキーマ設計のガイドライン:
- 主キーの戦略(UUID と serial)
- 外部キーのリレーションシップと連鎖処理
- クエリ最適化のためのインデックス設計
- 制約の適用
- デフォルト値と計算列
- JSON/JSONB の使用パターン
- 正規化の戦略
references/security.md - RLS と認証
本番環境向けのセキュリティ実装:
- 行レベルセキュリティポリシーのパターン
- auth.users との認証統合
- ロールベースのアクセス制御(RBAC)
- データ暗号化の戦略
- 監査ログのパターン
- マルチテナントのセキュリティモデル
references/tools-reference.md - MCP ツール
利用可能な MCP ツールに関する完全なドキュメント:
- 自然言語によるクエリ
- スキーマのイントロスペクション
- マイグレーション管理
- プロジェクト設定の取得
- データベースのブランチ作成(実験的)
- ログの分析とデバッグ
Supabase 公式ドキュメント
references/official-docs/row-level-security.md
Supabase 公式ドキュメントに基づく RLS の完全ガイド:
- 10 種類以上の RLS ポリシーパターン
- 実際のリポジトリに基づく本番環境の例
- よくある落とし穴と解決策
- RLS ポリシーのテスト
- パフォーマンスに関する考慮事項
references/official-docs/migrations.md
データベースマイグレーションガイド:
- 命令型マイグレーション(SQL ファイル)
- 宣言型スキーマ(schema.yml)
- マイグレーションのワークフローとベストプラクティス
- 互換性を損なう変更への対応
- テストでの Supabase ブランチの使用
本番環境のパターン
references/production-patterns.md
Twilio-Aldea(本番環境の SMS AI プラットフォーム)で使われている実例に基づくパターン:
- タイムアウトロジックを使ったセッション管理
- 二重永続化(soul + process memory)
- リージョン別の整理によるメッセージ保存
- 検証を伴う状態管理
- エラー処理とグレースフルデグラデーション
- 読み込みまたは作成のパターン
コード例
assets/examples/supabase-client.ts
サーバーサイドアプリケーション向けのシングルトンパターンを使ったクライアントの初期化
assets/examples/session-management.ts
自動タイムアウトと状態リセットを備えたセッション管理
assets/examples/memory-store.ts
二重永続化パターン(soul memory + process memory)
assets/examples/rls-policies.sql
一般的なユースケースを網羅する、本番環境ですぐに使える RLS ポリシーパターン 10 種類
GitHub リポジトリ(新規)
references/github/README.md
GitHub にある Supabase JS クライアントの公式 README(supabase/supabase-js、スター 4,045 件)
references/github/issues.md
よくある問題と解決策を示す 38 件の GitHub イシュー:
- JWT トークンの検証に関する問題
- Next.js キャッシュとの統合
- BigInt ID の処理
- WebSocket の競合状態
- RLS ヘッダーの伝播
- Realtime サブスクリプションのバグ
references/github/CHANGELOG.md
互換性を損なう変更とマイグレーションを含む完全なバージョン履歴
references/github/releases.md
詳細なリリースノートとマイグレーションガイドを含む 410 件の GitHub リリース
references/github/file_structure.md
ソースコードの構成を示すリポジトリの構造(521 ファイル)
このスキルを使う
初心者向け
ここから始めましょう:
- MCP の初期設定については、
references/mcp-setup.mdを読みます - クライアントのセットアップの基本については、
assets/examples/supabase-client.tsを確認します - スキーマ管理については、
references/official-docs/migrations.mdを学習します - MCP を使って簡単な CRUD 操作を練習します
- 上記のクイックリファレンス例 #1~3 を確認します
最初のプロジェクト:
- 安全に調査できるよう、読み取り専用モードで MCP をセットアップします
- RLS を適用したシンプルなユーザープロフィールテーブルを作成します
- MCP を使った自然言語クエリを練習します
- 最初のマイグレーションを作成します
中級者向け
知識を深める:
- 包括的な RLS パターンについては、
references/official-docs/row-level-security.mdを学習します - 本番環境に対応したポリシーについては、
assets/examples/rls-policies.sqlを確認します assets/examples/session-management.tsを使ってセッション管理を実装します- 高度な設計については、
references/database-patterns.mdを調べます - 上記のクイックリファレンス例 #4~7 を確認します
練習プロジェクト:
- 組織+メンバー+RLS を備えたマルチテナント SaaS アプリケーション
- トリガーを使った監査ログシステム
- タイムアウトロジックを備えたセッションベースの状態管理
- 時系列データの追跡(製品価格の履歴)
上級者向け
本番環境のパターンを習得する:
- 実環境で使われるパターンについては、
references/production-patterns.mdを学習します assets/examples/memory-store.tsを使って二重永続化を実装します- データベースをサービスごとに分けたマイクロサービスアーキテクチャを設計します
- インデックス戦略とクエリ分析によってパフォーマンスを最適化します
- 上記のクイックリファレンス例 #8~10 を確認します
高度な課題:
- CQRS パターンを使ったイベントソーシング
- マルチリージョンのレプリケーションと一貫性
- 負荷分散を備えた高可用性 MCP のデプロイ
- 動的なロール割り当てを伴う複雑な RLS ポリシー
- 数百万行のテーブルに対するパフォーマンス最適化
ナビゲーションのヒント
適切なドキュメントを見つける:
- MCP のセットアップに関する問題? →
references/mcp-setup.md - セキュリティ/RLS に関する質問? →
references/official-docs/row-level-security.mdまたはreferences/security.md - スキーマ設計の判断? →
references/database-patterns.mdまたはreferences/schema-design.md - 本番環境の例? →
references/production-patterns.mdまたはassets/examples/ - マイグレーション戦略? →
references/official-docs/migrations.md
クイック参照: 完全なドキュメントを調べずにすぐ使えるコードスニペットを確認するには、「クイックリファレンス例」セクションを使います。
ベストプラクティスのまとめ
データベース設計
- シンプルに始め、段階的に発展させる - 正規化した状態から始め、利用状況に応じて非正規化します
- 主キーには UUID を使う - 分散システムに適しており、連番からの推測を防げます
- JSONB の使用は控えめにする - 既知のフィールドには型付きカラムを優先します
- 初日から RLS を実装する - セキュリティは後付けではなく、最初から組み込みます
- スキーマをバージョン管理する - すべての変更にマイグレーションを使います
MCP の使用
- プロジェクトのスコープを設定する - 特定のプロジェクトにアクセスを制限します
- 読み取り専用モードを有効にする - 開発や調査に利用します
- ツールの手動承認を有効にしておく - 本番環境では有効のままにします
- API の使用状況を監視する - ダッシュボードを通じて操作を追跡します
- ブランチでテストする - スキーマ変更のテストにはブランチを使います
セキュリティ
- RLS ポリシーを実装する - アプリケーションレベルのセキュリティだけに頼ってはいけません
- サービスロールキーは慎重に使う - 必要な場合に限り RLS をバイパスします
- すべての操作を監査する - データベースの管理操作を記録します
- 機密データを暗号化する - PII の保護には PostgreSQL の暗号化を使います
- 定期的にセキュリティレビューを行う - RLS ポリシーを定期的に監査します
パフォーマンス
- 外部キーにインデックスを作成する - 結合に使うカラムには必ずインデックスを作成します
- EXPLAIN ANALYZE を使う - クエリの実行計画を把握します
- N+1 クエリを避ける - 結合または一括取得を使います
- マテリアライズドビュー - コストの高い分析クエリに使います
- コネクションプーリング - 高い同時実行性が求められる場合は pgBouncer を使います
よくあるワークフロー
自然言語によるデータベースクエリ
Ask Claude: "Show me all users who signed up last month but haven't completed their profile"
AI を使ったスキーマ設計
Ask Claude: "Design a schema for a multi-tenant SaaS application with organizations, users, and billing"
マイグレーションの生成
Ask Claude: "Generate a migration to add a 'status' column to the posts table with an enum type"
RLS ポリシーの作成
Ask Claude: "Create RLS policies so users can only see posts from organizations they're members of"
クエリの最適化
Ask Claude: "Analyze this query and suggest optimizations: SELECT * FROM orders WHERE user_id = '...' AND created_at > '2024-01-01'"
トラブルシューティング早見表
MCP 接続エラー
- API キーが正しく、有効期限が切れていないことを確認します
- MCP エンドポイントへのネットワーク接続を確認します
- 組織の権限が適切に設定されていることを確認します
claude mcp listを実行して、設定済みのサーバーを確認します
RLS ポリシーのエラー
- 異なるユーザーコンテキストでポリシーをテストします
- 現在のユーザーを確認するには
auth.uid()を使用します - サービスロールキーは RLS をバイパスすることを忘れないでください
- EXPLAIN を使ってポリシーを確認します:
EXPLAIN SELECT * FROM table_name;
マイグレーションの失敗
- マイグレーションは必ず最初にブランチ上でテストします
- 依存関係の問題(外部キー、トリガー)がないか確認します
- スキーマを変更する前に、データとの互換性を確認します
supabase db resetをローカルで実行し、最初からテストします
パフォーマンスの問題
- EXPLAIN ANALYZE でクエリプランを確認します
- 外部キーにインデックスが不足していないか確認します
- コネクションプールの使用状況を監視します
pg_stat_user_indexesを使ってインデックスの使用状況を追跡します
バージョン履歴
- v2.1(2026-04-21)- mcp-lite Edge Functions のデプロイ(コールドスタートゼロ)に対応するよう更新し、Docker を使ったセルフホスト MCP を追加。パブリックアルファ版の継続を明記
- v2.0(2025-11-01)- Supabase の公式ドキュメント、Twilio-Aldea の本番環境向けパターン、TypeScript/SQL の例、包括的な RLS ガイドを追加
- v1.0 - MCP のセットアップ、データベースのパターン、スキーマ設計、セキュリティ、ツールのリファレンスを含む初期スキルを作成