CtrlK
BlogDocsLog inGet started
Tessl Logo

g14wxz/commerce-database-architect

Database architecture skills, docs, and rules for high-demand multi-tenant commerce platforms (PostgreSQL source of truth, Neo4j as derived GraphRAG projection, transactional outbox, RLS-based tenant isolation). Includes live schema introspection workflow via explicit Supabase MCP/read-only schema sources.

77

Quality

97%

Does it follow best practices?

Impact

No eval scenarios have been run

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

mcp-safety.mdsteering/

MCP Safety Rules

These rules govern every interaction the agent has with Supabase MCP or any read-only schema-introspection MCP server. They are always on.

The user's database is real production-shaped data even in development. Mistakes at this layer are not undoable.


Server selection

  1. Canonical for this repo: /speckit.dbsync uses Supabase MCP source names. The three Supabase MCP sources are local-storestorm-tenant, dev-storestorm-tenant, and prod-storestorm-tenant. Hosted sources use read_only=true.

  2. Forbidden: @modelcontextprotocol/server-postgres. This package was archived July 2025 with a known SQL injection vulnerability (Datadog Security Labs disclosure, May 2025). Even if it appears in old .mcp.json files, it must be replaced.

  3. Approved alternatives:

    • Supabase MCP for Supabase projects, always with read_only=true for hosted schema awareness
    • postgres-mcp-pro or pgEdge Postgres MCP for non-Supabase Postgres targets, restricted/read-only
    • Other cloud-vendor MCPs only when configured read-only

Connection configuration

  1. The MCP source is read-only. Either:

    • PostgreSQL role with GRANT SELECT ON ALL TABLES IN SCHEMA <schemas> and no DML/DDL grants, OR
    • Server is configured in restricted/read-only access mode that strips non-SELECT statements before execution
  2. For direct Postgres-role MCP sources, the MCP role has SET default_transaction_read_only = on, statement_timeout = '5s', and idle_in_transaction_session_timeout = '10s'.

  3. The MCP source has no access to:

    • Functions with side effects (pg_terminate_backend, dblink_*, pg_read_file, pg_advisory_lock)
    • Tables containing tenant PII unless explicitly granted for the introspection task at hand
    • The replication slot management views

Connection target

  1. Production MCP queries run against a read replica, not the primary. If a connection string targets a primary in production, the agent warns and asks for confirmation.

  2. Secrets are never committed. Supabase sbp_... tokens belong in macOS Keychain through supawho or in operator secret stores, not in .mcp.json. Direct connection strings reference environment variables only:

    "env": { "DATABASE_URI": "${env:READONLY_DATABASE_URL}" }
  3. supawho may select the operator Supabase CLI account. Current Supabase CLI account names are dev-storestorm-tenant and prod-storestorm-tenant; MCP server names are local-storestorm-tenant, dev-storestorm-tenant, and prod-storestorm-tenant. MCP project verification remains mandatory; CLI identity is not schema evidence. prod-storestorm-tenant mutations require explicit current-session approval.

  4. The MCP server runs as a separate process under the developer's user — never as root, never inside the application container.

Query discipline

  1. No SELECT * from business tables. Project only the columns the introspection requires. Tenant data should not enter the LLM context unless the user explicitly asks.

  2. Every query has a LIMIT when targeting a table over 10,000 rows. For sampling, use TABLESAMPLE SYSTEM (1).

  3. No DDL or DML through the MCP. Even if the role is misconfigured to allow it, the agent refuses.

  4. No exploratory SELECT against tables with regulated data (prescription_records, payment_card_metadata) unless the user has explicitly scoped the request.

Audit & observability

  1. MCP queries against production replicas are logged with: timestamp, role, query text, row count, duration, request_id. The log lives in the database operator's observability stack, not in the project repo.

  2. The agent surfaces every MCP call in its response. The user can see which queries ran and why.

Failure handling

  1. If the MCP server is unavailable, the agent uses the cached snapshot in .specify/memory/current-schema-state.md and clearly states that it's operating on cached data.

  2. If a query returns suspicious data (e.g., a column type the snapshot didn't have, a missing table), the agent re-runs the introspection rather than reasoning on the discrepancy.

  3. If the agent detects the MCP source has more privileges than declared above (e.g., DML grants exist or hosted Supabase MCP is not read-only), it stops and reports a § XV violation before doing any introspection.

Reasoning boundary

  1. MCP results are factual for current state, but they are not authoritative for future state. Architectural decisions still flow through the constitution. The fact that a column exists in the database does not retroactively justify it.

  2. The agent never quotes user PII discovered via MCP back into the chat transcript. Counts, types, and structural facts are fine; row contents are not.

tile.json