npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

schema-navigator-mcp

v0.2.0

Published

MCP server for PostgreSQL schema introspection — tables, columns, FKs, RLS policies, constraints, functions. Works with Supabase, Neon, Railway, CockroachDB, local Postgres, Aurora.

Readme

schema-navigator-mcp

npm version License: MIT Node.js

MCP server for PostgreSQL schema introspection. Gives Claude live access to your database structure — columns, types, constraints, foreign keys, RLS policies, functions, and more.

Works with any PostgreSQL-compatible database: Supabase, Neon, Railway, CockroachDB, AWS Aurora, local Postgres.

Why

The most common bugs when working with databases:

  1. Wrong column namestotal_price doesn't exist, it's total_amount
  2. Invalid constraint values'complete' is not an allowed status
  3. RLS client mismatch — browser client blocked by row-level security
  4. Blind migrations — dropping a column referenced by 5 foreign keys

This server eliminates all four by giving your AI assistant live schema access.

Quick Start

Option 1: Supabase (no password needed)

The easiest setup for Supabase projects. Uses the Management API — no database password or connection string required.

  1. Get a Personal Access Token from supabase.com/dashboard/account/tokens
  2. Find your project ref in your dashboard URL: supabase.com/dashboard/project/<project-ref>

Add to your project's .mcp.json:

{
  "mcpServers": {
    "db": {
      "command": "npx",
      "args": ["-y", "schema-navigator-mcp@latest"],
      "env": {
        "SUPABASE_ACCESS_TOKEN": "sbp_...",
        "SUPABASE_PROJECT_REF": "your-project-ref"
      }
    }
  }
}

Or if you already have SUPABASE_URL or NEXT_PUBLIC_SUPABASE_URL set, the project ref is extracted automatically:

{
  "mcpServers": {
    "db": {
      "command": "npx",
      "args": ["-y", "schema-navigator-mcp@latest"],
      "env": {
        "SUPABASE_ACCESS_TOKEN": "sbp_...",
        "SUPABASE_URL": "${SUPABASE_URL}"
      }
    }
  }
}

Option 2: Direct connection (any PostgreSQL)

Works with any PostgreSQL-compatible database — Supabase, Neon, Railway, CockroachDB, AWS Aurora, local Postgres.

{
  "mcpServers": {
    "db": {
      "command": "npx",
      "args": ["-y", "schema-navigator-mcp@latest"],
      "env": { "DATABASE_URL": "${DATABASE_URL}" }
    }
  }
}

Set DATABASE_URL in your environment (e.g. .env.local) and restart Claude Code.

Priority

If both are set, DATABASE_URL takes priority (direct connection is faster and has no rate limits).

With the schema-nav Plugin

For slash commands (/db:table, /db:find, etc.) and auto-activated validation skills, install the companion schema-nav plugin.

Tools

7 read-only tools, each under 200 chars description (~4.9K total context cost):

| Tool | What it does | |------|-------------| | schema_overview | Database dashboard — all tables with row counts and sizes, views, enums, extensions, health warnings | | schema_table | Complete profile of a table/view/matview — columns, types, defaults, constraints, FKs, indexes, RLS, grants | | schema_find | Cross-schema search across tables, columns, functions, views, policies, enums, comments | | schema_relations | FK relationship graph — outbound and inbound references with cascade actions | | schema_functions | Function inspector — arguments, return type, language, volatility, security definer, source code | | schema_constraints | Value extractor — allowed values from CHECK constraints and ENUM types, merged | | schema_policies | RLS analyzer — enabled status, policy expressions, role-by-operation access matrix |

Example: schema_table

schema_table("orders") →
{
  "object_type": "table",
  "columns": [
    { "name": "id", "type": "uuid", "nullable": false, "default": "gen_random_uuid()" },
    { "name": "status", "type": "text", "nullable": false, "comment": "Order lifecycle state" },
    { "name": "total_amount", "type": "numeric", "nullable": false },
    ...
  ],
  "constraints": [
    { "type": "CHECK", "column": "status", "allowed_values": ["pending", "processing", "shipped", ...] }
  ],
  "fks_in": [
    { "from_table": "order_items", "from_column": "order_id", "on_delete": "CASCADE" }
  ],
  "rls_enabled": true,
  "row_count": 51200,
  "total_size": "32.1 MB"
}

Architecture

┌─────────────────────────────────────────────────────────┐
│  schema-navigator-mcp                                   │
│                                                         │
│  ┌─ DATABASE_URL ──► PgAdapter (pg.Pool)                │
│  │                    ├── BEGIN TRANSACTION READ ONLY    │
│  │                    ├── query (15s timeout)            │
│  │                    └── COMMIT                         │
│  │                                                      │
│  └─ SUPABASE_ACCESS_TOKEN ──► SupabaseAdapter           │
│                                ├── Management API       │
│                                ├── batch N queries → 1  │
│                                └── 30s timeout          │
│                                                         │
│  7 tools registered via MCP SDK                         │
│  stdio transport (JSON-RPC)                             │
└─────────────────────────────────────────────────────────┘

Direct connection (PgAdapter)

  • Read-only transactions — every query wrapped in BEGIN TRANSACTION READ ONLY. Cannot modify data.
  • Connection poolingpg.Pool with max 5 connections, 5s connect timeout, 30s idle timeout.
  • Query timeout — 15s statement_timeout prevents hanging queries.
  • Graceful shutdown — SIGINT/SIGTERM handlers close pool connections cleanly.

Supabase Management API (SupabaseAdapter)

  • Zero-password — authenticates via Personal Access Token, no database credentials needed.
  • Batch queries — multiple queries batched into a single API call using json_build_array, staying within the 10 req/min rate limit.
  • Parameter inlining$1, $2 placeholders safely inlined with SQL escaping (all params are Zod-validated schema/table names).
  • 30s timeout — per-request timeout with AbortController.

Universality

The server uses two query layers with automatic detection:

Universal (information_schema — SQL standard):

  • Tables, columns, data types, defaults, nullability
  • Foreign keys, CHECK constraints, UNIQUE constraints
  • Views, routines, triggers

PostgreSQL-specific (pg_catalog — graceful degradation):

  • RLS policies → returns [] + note on non-Postgres
  • ENUM types → returns []
  • Function source code → signature-only fallback
  • Table sizes, row estimates → null
  • Column comments → null

Detection runs once at startup via SELECT version().

Programmatic API

import { createSchemaNavigator } from "schema-navigator-mcp";

// Direct PostgreSQL connection
const server = await createSchemaNavigator("postgresql://...");

// Supabase Management API
const server = await createSchemaNavigator({
  accessToken: "sbp_...",
  projectRef: "your-project-ref",
});

// server is an McpServer instance — connect your own transport

Security

  • Read-only — direct connections use read-only transactions; Management API queries are all SELECT statements
  • No credentials storedDATABASE_URL / SUPABASE_ACCESS_TOKEN from environment only
  • No data access — introspects schema metadata, never reads table data
  • Parameterized queries — direct connections use native $1 parameters; Management API inlines with SQL escaping (all inputs are Zod-validated)

Requirements

  • Node.js >= 18
  • One of:
    • DATABASE_URL — any PostgreSQL-compatible connection string
    • SUPABASE_ACCESS_TOKEN + SUPABASE_PROJECT_REF (or SUPABASE_URL / NEXT_PUBLIC_SUPABASE_URL)

License

MIT