Skip to main content
Glama

SupaPIM

A schema-first CMS / PIM and a remote MCP server for Supabase, where every person — and every AI agent acting for them — works with exactly their own Postgres rights.

SupaPIM reads your database schema and builds an editing interface from it: lists, forms, image galleries, drag-and-drop ordering, a settings page per brand and a change history. The same rights also drive an MCP server, so Claude, ChatGPT or Cursor can read and edit your content on a person's behalf, and never more than that person may.

There is one identity (Supabase Auth) and one rights system (Postgres GRANTs, column grants and row-level security). SupaPIM adds no permission model of its own.

Made by AutomateThis! · Free to use · Licence

SupaPIM is not affiliated with, endorsed by, or sponsored by Supabase Inc.


Features

Content and product data

  • The UI is generated from your schema (via cms_api.describe()): every table the person may read appears, every column they may change is editable, everything else is read-only.

  • One Postgres schema per brand (e.g. nordwind, suedwind), each with its own menu group.

  • Brand settings page (display name, website, contact, default currency and locale, SEO defaults, logo), with currency and locale as dropdowns.

  • Images and files from Supabase Storage: upload, replace, rename (every row using the file follows), pick an existing file, alt text and title, galleries with several images per product, a list of files no record uses.

  • Drag-and-drop ordering in lists, enums as dropdowns, Markdown and HTML fields, references between tables in both directions.

  • Hints in Postgres comments (@cms(image, bucket=images), @cms(readonly), @cms(label=…), @cms(singleton) …), editable in SQL or Studio.

  • Change history per record from a generic audit log, with the person's e-mail and the OAuth client.

  • English and German UI, light and dark theme.

Rights

  • People are mapped to Postgres group roles (e.g. cms_admin, agency_nordwind). A Custom Access Token Hook puts that role into the access token; PostgREST and Storage switch into it.

  • Column grants decide which fields are editable, RLS decides which rows are visible, storage policies decide which files.

  • An agency can work for several brands through one role that is a member of the brand roles.

  • Admin area: invite people, assign roles, see the effective rights of each role, MFA (TOTP).

MCP server for AI agents

  • Remote MCP server (Streamable HTTP) at /cms/mcp. Supabase Auth is the OAuth 2.1 authorization server, with dynamic client registration and a consent page in the UI.

  • The server checks the person's token and passes the same token to PostgREST and the Storage API. It has no service key, no database access and no signing key.

  • Tools: whoami, list_tables, select_rows, insert_rows, update_rows, delete_rows, call_function (e.g. vector search), list_files, upload_file, download_file, create_signed_url.

  • Refusals are explained: "Role agency_nordwind may not change column price in nordwind.products. Allowed to update: name."

  • Rate limit per person and an access log without data values or tokens.

Related MCP server: Atomic CRM MCP Server

How it works

Person / AI agent ──▶ Supabase Auth (login or OAuth 2.1) ──▶ access token { role: agency_nordwind, email, … }
        │
        ├─ SupaPIM UI (/cms) ─────────┐
        └─ MCP server (/cms/mcp) ─────┴─▶ PostgREST / Storage API with the SAME token
                                              └─▶ SET ROLE agency_nordwind
                                                    → GRANT, column GRANT and RLS decide
                                                    → audit trigger records the e-mail and client

SupaPIM ships as one container image (UI, MCP server and consent page; the admin API runs from the same image as a separate service, the only one with the secret key) and one idempotent SQL migration (schemas cms, cms_api, audit). It plugs into an existing Supabase stack without changing Supabase's own files.

Requirements

  • Supabase self-hosted (self-hosted/v0.8.x, Envoy or Kong gateway) or Supabase Cloud (prepared, see the Cloud guide)

  • Postgres 15 or 17

  • Supabase Auth with the OAuth 2.1 server enabled, ES256 signing keys

Details: compatibility.

Install

Guide

Self-hosted Supabase

docs/install-selfhosted.md: unpack the package into your Supabase docker/ directory and run cms/install.sh all <admin-email>

Supabase Cloud

docs/install-cloud.md: run the container on any Docker host next to your Cloud project

Add a brand

docs/brand-bootstrap.md: install.sh brand acme --label "Acme Outdoor"

Upgrade / uninstall

docs/upgrade.md

Image storage on S3

docs/storage-s3.md

The image is published as ghcr.io/hammerschmied-group/supapim.

Connect an AI client

Add https://<your-supabase-host>/cms/mcp as a remote MCP server:

  • Claude Code: claude mcp add --transport http supapim https://<your-supabase-host>/cms/mcp, then /mcp → Authenticate.

  • claude.ai / Claude Desktop: Settings → Connectors → Add custom connector.

  • ChatGPT: Settings → Connectors → Create (developer mode).

The client registers itself, you sign in with your Supabase account and approve it on the consent page. From then on the agent works with your role.

Configuration of the MCP server (container environment):

Variable

Meaning

Default

SUPABASE_URL

where the server reaches Supabase (gateway; Cloud: https://<ref>.supabase.co)

SUPABASE_PUBLIC_URL

SUPABASE_PUBLIC_URL

what browsers and clients see

–

PUBLIC_BASE_URL

host under which /cms/mcp is public (base of the protected resource metadata)

SUPABASE_PUBLIC_URL

AUTH_ISSUER

expected iss

<SUPABASE_PUBLIC_URL>/auth/v1

SUPABASE_ANON_KEY

public key for the gateway

–

MCP_RATE_BURST, MCP_RATE_PER_MINUTE

rate limit per person

60, 120

MCP_MAX_UPLOAD_BYTES

upload limit

5 MiB

Local development

Requirements: Docker Desktop, Node ≥ 22, git, openssl.

scripts/start.sh            # first run: fetch the upstream stack, create .env with fresh local secrets, start, seed the demo
scripts/test.sh             # SQL, server, MCP chain, storage, security and UI (unit + Playwright) tests against the running stack
scripts/test-sql.sh         # the SQL migration in throwaway containers, Postgres 17 and 15 (no stack needed)
scripts/brand-bootstrap.sh <schema>              # set up a brand (repeatable)
scripts/agency.sh <name> --brand a --brand b     # one agency for several brands
scripts/reset.sh            # demo back to its seed state (~10 s); --wipe rebuilds everything
scripts/stop.sh             # stop, keep data

Service

URL

SupaPIM UI

http://localhost:55321/cms/ (dev server: npm run dev in apps/ui, http://localhost:55390/cms/)

MCP server

http://localhost:55321/cms/mcp

Supabase gateway and Studio

http://localhost:55321

Mailpit (invitations, magic links)

http://localhost:55326

Demo users (password: TEST_USER_PASSWORD in your local .env):

E-mail

Role

May

admin@example.com

cms_admin

edit both demo brands and the documents, manage people

agentur.nordwind@example.com

agency_nordwind

read Nordwind, change product names and image texts

agentur.suedwind@example.com

agency_suedwind

the same for Südwind

hr@example.com

hr_editor

read HR documents, manage the hr-files bucket

ohne.rolle@example.com

–

nothing

The demo also has the agency role agency_northstar for both brands.

Project layout

packages/sql/install.sql      the migration (schemas cms, cms_api, audit); idempotent and versioned, run as postgres
packages/sql/uninstall.sql    uninstaller (optionally keeps the audit log)
apps/server/                  Express: MCP server (src/mcp), admin API (src/admin, admin.mjs), UI delivery (src/ui)
apps/ui/                      the UI: react-admin + Vite, generated from describe(); see apps/ui/ARCHITECTURE.md
deploy/selfhosted/            the self-hosted package: compose files, Envoy/Kong gateway wrappers, install.sh
deploy/cloud/                 the Cloud variant: container (+ optional Caddy), check.sh, first-admin.sql
scripts/                      local stack, demo, brand and agency tools, tests, image and package builds
demo/                         demo brands, roles, data and files
docs/                         install, upgrade, compatibility, brands, storage, security

Security

The security model, the findings of the security review and an operator checklist are in docs/security/. Please report vulnerabilities privately via automatethis.pro, not as a public issue.

Licence

SupaPIM is free to use and source-available under the Business Source License 1.1 with an additional use grant: you may use and self-host it in production for your own organisation and brands, free of charge. Offering it as a hosted service to others, reselling or white-labelling it, and removing the "Made by AutomateThis!" notice need a separate agreement. Each version becomes Apache-2.0 four years after its release. Plain-English summary: LICENSING.md.

Need help with installation, custom fields or a full PIM/CMS setup? AutomateThis! builds it for you.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Connects AI assistants to Supabase projects, enabling them to manage tables, query data, deploy Edge Functions, handle migrations, and access project resources through natural language commands.
    Apache 2.0
  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    Enables AI agents to securely read and write data to an Atomic CRM instance via SQL queries. It features OAuth 2.1 authentication through Supabase and automatically enforces Row Level Security to protect user data.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Experimental read-only MCP for Supabase application data: memory_search, memory_get and memory_list_recent under user-bound PostgreSQL RLS. Setup and demo: https://github.com/jryski/Supabase_user_MCP/blob/main/docs/GETTING_STARTED.md . Public preview is POSIX-only and synthetic-only; native Windows, hosted OAuth, one-click installation and writes are not available.
    Apache 2.0