The Goal

By the end of this blueprint, you and every member of your team will share a snippet library that Claude can read and write to. Anyone with Claude Code can point it at your server URL, sign in once with Supabase Auth, and from then on:

"Save this prompt as 'incident postmortem template' and put it in our team workspace."

"Pull up our eval-rubric snippet."

"What snippets has the team saved about RAG retrieval?"

…will all just work — across machines, across teammates, with proper auth and per-workspace visibility.

What Makes This Different From the Other MCP Blueprint

The existing Build Your Own MCP Server blueprint runs your server locally over STDIO with no auth. This one is the production cousin:

AspectLocal MCP blueprintThis blueprint
TransportSTDIO (subprocess)Streamable HTTP (remote)
AuthNone — local trustFull OAuth 2.1 (Supabase)
StorageSQLite on diskPostgres + Supabase Auth
AudienceSingle userA whole team
DeploymentNone — Claude launches itSupabase Edge Functions
MCP clientsClaude Code on your machineClaude Code / Desktop on any machine

If you've done the local one, this is the natural next step. If you haven't, you'll be fine — we re-explain the relevant MCP concepts as we go.

Why "Snippets" and Not Real Claude Code Skills

A Claude Code skill is a directory with a SKILL file plus optional supporting files, loaded out of ~/.claude/skills/. Powerful, but the format is opinionated and pulls supporting files from disk — awkward to model as a database row.

We're storing free-form prompt snippets: a title, a body of markdown, and tags. They're easier to author, search, and version. If you want to load them as actual Claude Code skills later, the body is markdown — a thin sync script can write each snippet to its own SKILL in ~/.claude/skills/. We'll cover this in the final step.

The Stack

ChoiceWhy
Supabase Edge Functions (Deno)First-class OAuth 2.1 server, RLS-native Postgres, single supabase functions deploy command, free tier covers small teams.
TypeScript + HonoHono runs on Deno + Node + Bun, has clean middleware, and the MCP SDK ships TypeScript types.
Official MCP SDK@modelcontextprotocol/sdk — Anthropic's reference, handles the JSON-RPC plumbing, supports Streamable HTTP out of the box.
Supabase OAuth 2.1 ServerGA as of 2026. Implements RFC 8414 (metadata), RFC 7591 (dynamic client registration), RFC 9728 (protected resource metadata) — exactly what the MCP spec requires.
Postgres with RLSMulti-tenancy enforced in the database, not in app code. Bugs in tool implementations can't leak data across workspaces.

How the Pieces Fit Together

┌────────────────────────┐
│  Claude Code (CLI)     │
│  or Claude Desktop     │
└────────────┬───────────┘
             │ 1. MCP request (no token yet)

┌────────────────────────────────────────────┐
│  MCP Edge Function                          │
│  https://<ref>.supabase.co/functions/v1/mcp │
│                                              │
│  • 401 + WWW-Authenticate (RFC 9728)        │
│  • Validates Supabase JWT (RFC 8707 aud)    │
│  • Forwards user token → Supabase client    │
│  • Exposes MCP tools + resources            │
└────────┬─────────────────────┬──────────────┘
         │ 2. Discovers AS     │ 5. Bearer-authed
         ▼                     ▼
┌────────────────────┐    ┌──────────────────────┐
│  Supabase Auth     │    │  Postgres (Supabase) │
│  OAuth 2.1 server  │    │  • workspaces        │
│                    │    │  • workspace_members │
│  • /.well-known/   │    │  • snippets          │
│    oauth-          │    │                       │
│    authorization-  │    │  RLS scoped by        │
│    server          │    │  workspace membership │
│  • Dynamic client  │    └──────────────────────┘
│    registration    │
└────────────────────┘

         │ 3. Browser opens, user signs in
         │ 4. Token returned via redirect_uri

   ┌──────────────────┐
   │  User's browser  │
   └──────────────────┘

Five things happen the first time Claude calls the server, in order:

  1. Claude makes an unauthenticated MCP request.
  2. The server responds 401 with a WWW-Authenticate header pointing at its Protected Resource Metadata document. Claude reads that doc, which names Supabase as the authorization server, and discovers Supabase's well-known OAuth endpoints.
  3. Claude (acting as an OAuth 2.1 client with PKCE) opens the user's browser at Supabase's authorization endpoint. The user signs in.
  4. Supabase redirects back with an authorization code, Claude exchanges it for an access token, and stores the refresh token.
  5. From now on, every MCP request includes Authorization: Bearer <jwt>. The Edge Function validates the JWT, forwards it into a per-request Supabase client, and Postgres RLS does the rest.

Every later request from any teammate's Claude follows the same flow.

The MCP Surface We'll Expose

Once auth is wired, the actual snippet API stays compact:

Tools (actions Claude can take):

  • list_snippets({ workspace?, tag?, search? }) — list snippets the calling user can see.
  • get_snippet({ id }) — fetch one snippet's full body.
  • save_snippet({ title, body, tags?, workspace }) — create or update.
  • share_snippet({ id, visibility }) — change privateworkspacepublic.
  • list_workspaces() — workspaces this user is a member of.
  • invite_to_workspace({ workspace, email, role }) — owners only.

Resources (data Claude can browse):

  • snippets://workspace/<workspace_id> — a workspace's snippet collection.
  • snippets://mine — the user's private snippets.

Eleven steps, end-to-end deployed in production.

What You'll Need Before Step 2

  • A Supabase account (supabase.com — free tier is fine).
  • The Supabase CLI: brew install supabase/tap/supabase (or other install methods).
  • Node.js 18+ (for the build steps; Deno comes bundled with the Supabase CLI for the runtime).
  • Claude Code or Claude Desktop installed.
  • A code editor with TypeScript support.

Step 2 sets up the Supabase project and scaffolds the repo.