Supabase MCP Integration Guide¶
This guide shows how to use the Supabase Model Context Protocol (MCP) tools with your Juddges App database.
π§ Available MCP Tools¶
Based on the MCP tools available in your Claude Code session, you can interact with your Supabase database programmatically:
Database Schema Operations¶
mcp__supabase__list_tables- List all tables in your databasemcp__supabase__list_extensions- List PostgreSQL extensions (pgvector, etc.)mcp__supabase__list_migrations- View migration history
Data Operations¶
mcp__supabase__execute_sql- Run SQL queries (SELECT, UPDATE, DELETE)mcp__supabase__apply_migration- Apply new database migrations
Monitoring & Analytics¶
mcp__supabase__get_logs- View service logs (API, Postgres, Auth, etc.)mcp__supabase__get_advisors- Get security & performance recommendations
Project Management¶
mcp__supabase__get_project_url- Get your project's API URLmcp__supabase__get_publishable_keys- Get API keys for client access
TypeScript Type Generation¶
mcp__supabase__generate_typescript_types- Generate TypeScript types from schema
Branching (Development Environments)¶
mcp__supabase__create_branch- Create development branchmcp__supabase__list_branches- List all branchesmcp__supabase__merge_branch- Merge branch to production
π Common Usage Examples¶
Example 1: List Tables¶
Check what tables exist in your database:
// Using MCP tool
mcp__supabase__list_tables({
schemas: ["public"]
})
// Expected response:
// Tables: judgments, auth.users, ...
Example 2: Query Judgments¶
Retrieve judgments from your database:
-- Using execute_sql tool
SELECT
id,
case_number,
jurisdiction,
title,
decision_date,
court_name
FROM judgments
WHERE jurisdiction = 'PL'
ORDER BY decision_date DESC
LIMIT 10;
Example 3: Count by Jurisdiction¶
Get statistics on your judgment data:
SELECT
jurisdiction,
COUNT(*) as total_judgments,
COUNT(DISTINCT court_name) as unique_courts,
MIN(decision_date) as earliest_date,
MAX(decision_date) as latest_date
FROM judgments
GROUP BY jurisdiction;
Example 4: Semantic Search¶
Search judgments by vector similarity:
-- First, you'd generate an embedding for the query
-- Then search using the function we created:
SELECT * FROM search_judgments_by_embedding(
ARRAY[0.1, 0.2, ...]::vector(768), -- Your query embedding
0.7, -- Similarity threshold
10, -- Number of results
'PL' -- Filter by jurisdiction (optional)
);
Example 5: Full-Text Search¶
Search judgments using PostgreSQL full-text search:
SELECT * FROM search_judgments_by_text(
'criminal appeal tax liability', -- Search query
'UK', -- Filter by jurisdiction (optional)
20 -- Number of results
);
Example 6: Get Recent Judgments¶
Query the most recently added judgments:
SELECT
case_number,
jurisdiction,
title,
decision_date,
created_at
FROM judgments
ORDER BY created_at DESC
LIMIT 20;
Example 7: Check Embeddings Status¶
See how many judgments have embeddings:
SELECT
jurisdiction,
COUNT(*) as total,
COUNT(embedding) as with_embeddings,
ROUND(100.0 * COUNT(embedding) / COUNT(*), 2) as percentage
FROM judgments
GROUP BY jurisdiction;
Example 8: Search by Keywords¶
Find judgments matching specific keywords:
SELECT
case_number,
title,
keywords,
jurisdiction
FROM judgments
WHERE keywords && ARRAY['tax', 'liability'] -- Overlaps with keywords
ORDER BY decision_date DESC
LIMIT 10;
π Security & Access Control¶
Row Level Security (RLS)¶
If you want to enable RLS for user-specific access:
-- Enable RLS on judgments table
ALTER TABLE judgments ENABLE ROW LEVEL SECURITY;
-- Allow public read access (all users can view judgments)
CREATE POLICY "Allow public read access"
ON judgments
FOR SELECT
TO public
USING (true);
-- Only authenticated users can insert
CREATE POLICY "Authenticated users can insert"
ON judgments
FOR INSERT
TO authenticated
WITH CHECK (true);
-- Only service role can update/delete
CREATE POLICY "Service role full access"
ON judgments
FOR ALL
TO service_role
USING (true);
API Key Management¶
// Get your publishable keys
mcp__supabase__get_publishable_keys()
// Returns:
// - anon key (safe for client-side)
// - service_role key (server-side only, never expose)
π Monitoring & Performance¶
View API Logs¶
// Check API request logs
mcp__supabase__get_logs({
service: "api" // Options: api, postgres, auth, storage, realtime
})
Get Security Advisors¶
// Check for security issues
mcp__supabase__get_advisors({
type: "security" // Options: security, performance
})
// Common advisories:
// - Missing RLS policies
// - Unindexed foreign keys
// - Exposed service role keys
Performance Optimization¶
-- Check query performance
EXPLAIN ANALYZE
SELECT * FROM judgments
WHERE jurisdiction = 'UK'
AND decision_date > '2020-01-01';
-- Check index usage
SELECT
schemaname,
tablename,
indexname,
idx_scan as scans,
idx_tup_read as tuples_read
FROM pg_stat_user_indexes
WHERE schemaname = 'public'
ORDER BY idx_scan DESC;
π Development Workflow¶
Create Development Branch¶
For testing schema changes without affecting production:
// Create a development branch
mcp__supabase__create_branch({
name: "develop",
confirm_cost_id: "cost_id_from_confirmation"
})
// List branches
mcp__supabase__list_branches()
// Work on your branch, then merge when ready
mcp__supabase__merge_branch({
branch_id: "your_branch_id"
})
π¨ TypeScript Type Generation¶
Generate TypeScript types for your frontend:
// Generate types from your schema
mcp__supabase__generate_typescript_types()
// Save to file: frontend/types/supabase.ts
// Use in your Next.js app:
// import { Database } from '@/types/supabase'
π Advanced Queries¶
Complex Search with Filters¶
SELECT
j.id,
j.case_number,
j.title,
j.decision_date,
j.court_name,
ts_rank(
to_tsvector('english', j.full_text),
plainto_tsquery('english', 'criminal liability')
) as relevance
FROM judgments j
WHERE
j.jurisdiction = 'UK'
AND j.decision_date BETWEEN '2020-01-01' AND '2024-12-31'
AND j.case_type = 'Criminal'
AND to_tsvector('english', j.full_text) @@
plainto_tsquery('english', 'criminal liability')
ORDER BY relevance DESC, j.decision_date DESC
LIMIT 20;
Aggregate Statistics¶
SELECT
DATE_TRUNC('year', decision_date) as year,
jurisdiction,
court_name,
COUNT(*) as judgment_count
FROM judgments
WHERE decision_date IS NOT NULL
GROUP BY year, jurisdiction, court_name
ORDER BY year DESC, judgment_count DESC;
Similar Cases (Vector Similarity)¶
-- Find cases similar to a specific case
WITH target_case AS (
SELECT embedding
FROM judgments
WHERE case_number = 'I ACa 123/21'
)
SELECT
j.case_number,
j.title,
1 - (j.embedding <=> tc.embedding) as similarity
FROM judgments j, target_case tc
WHERE j.embedding IS NOT NULL
AND j.case_number != 'I ACa 123/21'
ORDER BY j.embedding <=> tc.embedding
LIMIT 10;
π οΈ Maintenance Tasks¶
Vacuum and Analyze¶
Keep your database performant:
Check Database Size¶
SELECT
pg_size_pretty(pg_database_size(current_database())) as db_size,
pg_size_pretty(pg_relation_size('judgments')) as judgments_table_size,
pg_size_pretty(pg_indexes_size('judgments')) as judgments_indexes_size;
Backup Data¶
-- Export to JSON (use execute_sql with COPY TO)
COPY (
SELECT json_agg(t)
FROM (
SELECT * FROM judgments
WHERE jurisdiction = 'PL'
LIMIT 100
) t
) TO '/tmp/polish_judgments_backup.json';
π Resources¶
- Supabase Docs: https://supabase.com/docs
- PostgreSQL Docs: https://www.postgresql.org/docs/
- pgvector Docs: https://github.com/pgvector/pgvector
- MCP Specification: https://modelcontextprotocol.io/
Pro Tip: Use the MCP tools in your Claude Code sessions to quickly query and manage your Juddges database without leaving your development environment!