Skip to content

How Do You Set Up Supabase Backend with Claude Code MCP? A Complete Guide

I kept switching between Claude Code, the Supabase dashboard, and my terminal trying to set up a backend. Every time I needed to add a table, tweak an RLS policy, or configure auth, I lost my train of thought. I’d forget which table I was modifying, what policy I had already created, and spend precious minutes just getting back into context.

Then someone on Reddit mentioned that Supabase MCP could wire up my entire backend layer without leaving Claude Code. But they also said something confusing: “migrations still need supabase cli.” I wasn’t sure where the line was drawn.

The Problem

I wanted Claude Code to be my single interface for backend development. I thought installing the Supabase MCP would handle everything. I was wrong.

After hours of trial and error, I discovered the boundary: MCP handles interactive operations, CLI handles migrations and local development. Understanding this split is crucial for a smooth workflow.

What I Tried First (And Failed)

I started by adding the Supabase MCP to my Claude Code configuration:

{
"mcpServers": {
"supabase": {
"command": "npx",
"args": ["-y", "@supabase/mcp-server-supabase"],
"env": {
"SUPABASE_ACCESS_TOKEN": "your-access-token",
"SUPABASE_PROJECT_ID": "your-project-id"
}
}
}
}

I fired up Claude Code and asked it to create a users table. It worked. Then I asked it to set up RLS policies. That worked too. I thought I was done.

Then I tried to run a migration. Claude Code couldn’t do it. I got confused - wasn’t MCP supposed to handle everything?

Understanding the Boundary

The Reddit comment that confused me became clear after I hit this wall:

“Migrations still need supabase cli. but once that’s wired, the mcp handles the rest of the backend layer without leaving claude code.”

Here’s what each tool handles:

TaskToolWhy
Create tablesMCPInteractive, exploratory work
Set up RLS policiesMCPSecurity configuration
Configure auth providersMCPOne-time setup
Deploy edge functionsMCPQuick iterations
Run migrationsCLIVersion control, repeatable
Local developmentCLIOffline testing
Branch managementCLITeam collaboration

The MCP works against your remote project directly. It’s perfect for experimentation and quick changes. The CLI manages your local development environment and migration history.

The Correct Workflow

Once I understood the boundary, I restructured my workflow:

Step 1: Set Up CLI First (One-Time)

Terminal window
# Install Supabase CLI
npm install -g supabase
# Login to Supabase
supabase login
# Link to your project
supabase link --project-ref your-project-id
# Initialize local development
supabase init
# Create your first migration
supabase migration new initial_schema

This creates a supabase/migrations/ folder that tracks all your schema changes. This is your source of truth.

Step 2: Configure MCP for Daily Work

Now I can use Claude Code with MCP for most operations:

Creating Tables via MCP:

I just ask Claude Code:

“Create a users table with id, email, created_at, and a profiles table linked to it”

Claude Code runs the SQL directly on my remote project:

CREATE TABLE users (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
email text UNIQUE NOT NULL,
created_at timestamptz DEFAULT now()
);
CREATE TABLE profiles (
id uuid PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
display_name text,
avatar_url text,
updated_at timestamptz DEFAULT now()
);

Setting Up RLS via MCP:

“Enable row-level security on the profiles table. Users should only see their own profile.”

ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can read own profile" ON profiles
FOR SELECT USING (auth.uid() = id);
CREATE POLICY "Users can update own profile" ON profiles
FOR UPDATE USING (auth.uid() = id);

Auth Configuration via MCP:

“Set up Google OAuth and email verification for the auth provider”

Claude Code configures auth settings through the Management API. No dashboard visits needed.

Step 3: Sync Back to CLI (When Ready)

When I’m happy with my changes, I sync them back to my local migrations:

Terminal window
# Generate a migration from current remote state
supabase db diff --schema public --use-migra
# Apply to local
supabase db reset

This captures the schema changes I made via MCP into version-controlled migration files.

Common Mistakes I Made

Mistake 1: Trying to Run Migrations Through MCP

I kept asking Claude Code to “run migrations.” It couldn’t. MCP doesn’t have access to your local migration files or the ability to generate new ones. That’s CLI territory.

Mistake 2: Skipping CLI Setup Entirely

I thought I could bypass the CLI. The result: no migration history, no local development environment, no way to collaborate with my team. I had to rebuild everything.

Mistake 3: Using MCP for Local Development

I tried to use MCP against my local Supabase instance. It doesn’t work that way. MCP connects to the remote project. For local work, use the CLI:

Terminal window
supabase start
supabase db reset

Mistake 4: Not Understanding the “Remote” Part

MCP makes changes on your production project (or whatever project you linked). I accidentally created test tables in production. Now I always link MCP to a development project first.

Why This Separation Matters

The CLI + MCP split actually makes sense:

  1. MCP for Exploration: When I’m figuring out my schema, testing queries, or tweaking RLS policies, I want immediate feedback. MCP gives me that.

  2. CLI for Discipline: When I’m ready to commit changes, I need version control, reproducible deployments, and team collaboration. CLI provides that.

  3. Safety: MCP changes are immediate. CLI migrations are reviewed before application. This prevents accidental production breakage.

Edge Functions: The Gray Area

Edge functions are interesting. You can create and deploy them through MCP:

// Claude Code creates this via MCP
Deno.serve(async (req) => {
const { name } = await req.json()
return new Response(JSON.stringify({ message: `Hello ${name}!` }), {
headers: { 'Content-Type': 'application/json' }
})
})

But for serious development, I still use the CLI for local testing:

Terminal window
supabase functions serve my-function --env-file .env.local

MCP is great for quick deployments, CLI for the development cycle.

  • Model Context Protocol (MCP): MCP is an open protocol that lets Claude interact with external services. The Supabase MCP server uses the Management API to control your project.

  • Supabase Management API: The MCP server uses this REST API under the hood. You can call it directly if needed, but MCP provides a cleaner interface.

  • Row Level Security (RLS): Postgres feature that restricts which rows users can access. Essential for multi-tenant apps. MCP makes policy creation conversational.

  • Supabase CLI vs Dashboard: The CLI provides infrastructure-as-code benefits. The Dashboard is visual but not version-controlled. MCP bridges the gap by being programmable.

References

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments