@rip-user/rls-debugger-mcp
Version:
AI-powered MCP server for debugging Supabase Row Level Security policies with Claude structured outputs
327 lines (249 loc) • 8.27 kB
Markdown
# Quick Start Guide
## What Was Built
An AI-powered MCP server that debugs Supabase RLS policies using Claude's latest capabilities:
- **Structured outputs** via native `response_format` API (Nov 14, 2025 release)
- **MCP 2025-06-18 compliance** with `outputSchema` and `title` fields on all tools
- **Configurable model selection** via `CLAUDE_MODEL` environment variable
- **Memory system** for persisting debugging knowledge across sessions
- **Built-in RLS documentation** - no need to fetch from web during analysis
- **Policy logic compilation** - visualizes how PERMISSIVE and RESTRICTIVE policies combine
- **Companion Skills** - optional systematic debugging workflows
## Prerequisites
1. **Node.js 18+** installed
2. **Supabase project** with RLS policies to debug
3. **Anthropic API key** for Claude access
4. **Supabase service role key** (has admin access, bypasses RLS)
## Installation
### Via NPM (Recommended)
```bash
# Use via npx (no installation needed)
npx @rip-user/rls-debugger-mcp
# Or install globally
npm install -g @rip-user/rls-debugger-mcp
```
### Via Claude Code CLI
```bash
# Project-specific
claude mcp add --transport stdio \
--command "npx" \
--arg "-y" \
--arg "@rip-user/rls-debugger-mcp" \
rls-debugger
# Global (all projects)
claude mcp add --scope user --transport stdio \
--command "npx" \
--arg "-y" \
--arg "@rip-user/rls-debugger-mcp" \
rls-debugger
```
### From Source (Development)
```bash
git clone https://github.com/rip-user/rls-debugger-mcp
cd rls-debugger-mcp
npm install
npm run build
```
## Configuration
### Option 1: Claude Code (Recommended)
Create `.mcp.json` in your project:
```json
{
"mcpServers": {
"rls-debugger": {
"command": "npx",
"args": ["-y", "@rip-user/rls-debugger-mcp"],
"env": {
"SUPABASE_URL": "https://your-project.supabase.co",
"SUPABASE_SERVICE_KEY": "eyJ...",
"ANTHROPIC_API_KEY": "sk-ant-...",
"CLAUDE_MODEL": "claude-sonnet-4-5-20250514"
}
}
}
}
```
**Configuration Scopes**:
- Project: `.mcp.json` (committed to git)
- User: `~/.mcp.json` (global across all projects)
- Local: `.mcp.local.json` (gitignored overrides)
### Option 2: Claude Desktop
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):
```json
{
"mcpServers": {
"rls-debugger": {
"command": "npx",
"args": ["-y", "@rip-user/rls-debugger-mcp"],
"env": {
"SUPABASE_URL": "https://your-project.supabase.co",
"SUPABASE_SERVICE_KEY": "eyJ...",
"ANTHROPIC_API_KEY": "sk-ant-..."
}
}
}
}
```
### Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| `SUPABASE_URL` | Yes | Your Supabase project URL |
| `SUPABASE_SERVICE_KEY` | Yes | Service role key (admin access) |
| `ANTHROPIC_API_KEY` | Yes | Anthropic API key |
| `CLAUDE_MODEL` | No | Model to use (default: `claude-sonnet-4-5-20250514`) |
| `MEMORY_DIR` | No | Memory storage location (default: `./.rls-memory`) |
## Usage Examples
### 1. Debug Access Denial
```
Why can't user abc-123 with admin role see document xyz-456?
The user has a team_members record with role 'admin'.
```
The tool will:
- Fetch all relevant RLS policies
- Load saved knowledge from previous sessions
- Analyze each policy to see if it grants access
- Identify the root cause
- Suggest fixes with SQL
- Assess risk level
### 2. Understand Policy Logic
```
Show me how policies on the documents table combine
```
Returns a decision tree showing:
- PERMISSIVE policies (OR logic)
- RESTRICTIVE policies (AND logic)
- Complete evaluation flow
### 3. Search Documentation
```
Search RLS docs for "PERMISSIVE vs RESTRICTIVE"
```
Gets relevant documentation sections with examples.
### 4. Save Knowledge
After fixing an issue:
```
Save to memory: documents requires team_members record.
Fixed by updating admin creation to always create team_members entry.
Related tables: documents, team_members
```
## Important Notes
### Supabase RPC Function Required
The server expects an `exec_sql` RPC function in Supabase. If you don't have it, create it:
```sql
CREATE OR REPLACE FUNCTION exec_sql(query text)
RETURNS json
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
DECLARE
result json;
BEGIN
EXECUTE query INTO result;
RETURN result;
END;
$$;
```
**Warning:** This function allows arbitrary SQL execution. Only call it with the service role key, never expose it to clients.
### Alternative: Direct PostgreSQL Access
If you can't use `exec_sql`, modify `src/rls-queries.ts` to use direct PostgreSQL connection:
```typescript
import { Pool } from 'pg';
const pool = new Pool({
connectionString: process.env.DATABASE_URL
});
export async function fetchAllPolicies(): Promise<RLSPolicy[]> {
const result = await pool.query(GET_ALL_RLS_POLICIES);
return result.rows;
}
```
## How It Works
### Structured Outputs (Nov 14, 2025 API)
Uses Claude's native `response_format` with JSON Schema for guaranteed structured responses:
```typescript
const response = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250514',
betas: ["structured-outputs-2025-11-13"],
response_format: {
type: "json_schema",
json_schema: {
name: "rls_analysis",
strict: true,
schema: {
type: 'object',
properties: { /* analysis schema */ },
required: [...],
additionalProperties: false // Strict mode
}
}
},
messages: [...]
});
```
This ensures **zero JSON parsing errors** and consistent output structure.
### Memory System
Stores debugging insights in `.rls-memory/policy_knowledge.json`:
```json
[
{
"type": "correction",
"content": "documents requires team_members record",
"tables": ["documents", "team_members"],
"timestamp": "2025-11-15T10:30:00Z"
}
]
```
Next time you analyze these tables, this knowledge is included in the prompt.
### Built-in Documentation
The server includes Supabase RLS documentation covering:
- Policy types (PERMISSIVE vs RESTRICTIVE)
- Policy commands (SELECT, INSERT, UPDATE, DELETE)
- Auth helpers (auth.uid(), auth.jwt())
- Performance tips
- Common patterns
- Troubleshooting
This documentation is **included in Claude's prompt** during analysis, so it can reference official best practices.
## Available Tools
1. **analyze_rls_policies** - AI-powered debugging
2. **compile_policy_logic** - Generate decision trees
3. **list_all_policies** - List all policies
4. **save_policy_knowledge** - Save insights to memory
5. **get_policy_knowledge** - Retrieve saved insights
6. **get_memory_summary** - View memory statistics
7. **get_rls_documentation** - Get specific docs
8. **search_rls_docs** - Search documentation
9. **get_all_rls_concepts** - Get all docs at once
## Troubleshooting
### "Failed to fetch RLS policies"
- Check `SUPABASE_URL` and `SUPABASE_SERVICE_KEY` are correct
- Verify the `exec_sql` RPC function exists
- Try the alternative PostgreSQL connection approach
### "ANTHROPIC_API_KEY not set"
- Add your Anthropic API key to the environment variables
- Get one at https://console.anthropic.com/
### Build errors
```bash
rm -rf dist/ node_modules/
npm install
npm run build
```
## Companion Skills
Optional Claude Skills enhance the MCP server with procedural knowledge:
```bash
# Global installation (recommended)
mkdir -p ~/.claude/skills
cp -r examples/skills/rls-debugger ~/.claude/skills/
# Project-local installation
mkdir -p .claude/skills
cp -r examples/skills/rls-debugger .claude/skills/
```
**Skills provide**:
- 5-step systematic debugging workflow
- Common RLS pattern recognition (multi-tenant, role-based, hierarchical)
- Performance optimization tips
- Best practices and common issue detection
- Automatic activation when you mention RLS debugging
See `examples/skills/rls-debugger/README.md` for details.
## Next Steps
1. **Test the server**: Ask Claude to analyze a specific RLS issue
2. **Build knowledge**: Save insights as you debug issues
3. **Reference docs**: Use the built-in documentation tools
4. **Extend**: Add custom tools for your specific use cases
See `README.md` for complete documentation and `examples/usage-examples.md` for detailed scenarios.