Installation
Requirements
Section titled “Requirements”- PostgreSQL 17 or newer. PostgreSQL 17 and 18 are tested; pgvis refuses to start against an older server. No libpq or other system Postgres library is needed — the driver is pure Rust.
- Or SQLite — bundled into the binary, no system dependency.
From Source (Cargo)
Section titled “From Source (Cargo)”Requires a current stable Rust toolchain (edition 2024; the repository’s rust-toolchain.toml pins the stable channel).
# Clone the repositorygit clone https://github.com/pgvis/pgvis.gitcd pgvis
# Build release binary (includes Postgres + SQLite + MCP support)cargo build --release --bin pgvis
# The binary is at ./target/release/pgvis./target/release/pgvis --versionFeature flags
Section titled “Feature flags”The pgvis binary always includes the PostgreSQL and SQLite backends. It has one feature:
| Feature | Default | Description |
|---|---|---|
mcp | ✓ | The pgvis mcp subcommand (stdio) and serve --mcp-http (Streamable HTTP) |
Backend selection is a feature of the pgvis-lib crate, for embedding pgvis in your own application:
pgvis-lib feature | Default | Description |
|---|---|---|
postgres | ✓ | PostgreSQL backend (pure Rust driver, rustls for TLS) |
sqlite | ✓ | SQLite backend (bundled, no system dependency) |
mcp | ✓ | MCP server support (stdio + Streamable HTTP) |
For example, a Postgres-only embedding:
pgvis-lib = { git = "https://github.com/pgvis/pgvis", default-features = false, features = ["postgres"] }If you have Nix with flakes enabled:
# Build the binarynix build github:pgvis/pgvis
# Run directly without installing (local experiment: no auth)nix run github:pgvis/pgvis -- --dsn "postgres://localhost/mydb" serve --insecure-no-auth
# Development shell: Rust toolchain, PostgreSQL, pgcli,# PostgREST, cargo-nextest, Node.js for the websitenix developThe flake provides a complete development environment with all system dependencies.
Docker (Coming Soon)
Section titled “Docker (Coming Soon)”docker run -e PGVIS_DSN="postgres://host.docker.internal/mydb" \ -e PGVIS_ANON_ROLE="web_anon" \ -p 3000:3000 \ ghcr.io/pgvis/pgvis serve --bind 0.0.0.0:3000Verifying Installation
Section titled “Verifying Installation”# Check versionpgvis --version
# Show helppgvis --help
# Test against a databasepgvis --dsn "postgres://localhost/mydb" inspect | head -20CLI Reference
Section titled “CLI Reference”pgvis [OPTIONS] [COMMAND]
Options: -d, --dsn <DSN> Database connection string [env: PGVIS_DSN] -c, --config <FILE> Path to TOML config file [env: PGVIS_CONFIG] -h, --help Print help -V, --version Print version
Commands: serve Start the HTTP server (REST + optional MCP) mcp Run an MCP server over stdio openapi Print the OpenAPI 3.0 document and exit inspect Dump the introspected schema cache as JSONGlobal options go before the command: pgvis --dsn … serve, not pgvis serve --dsn ….
pgvis serve
Section titled “pgvis serve”pgvis serve [OPTIONS]
Options: -b, --bind <ADDR> Bind address [default: 127.0.0.1:3000] [env: PGVIS_BIND] --insecure-no-auth Serve without jwt_secret or anon_role (every request runs as the DSN's role) [env: PGVIS_INSECURE_NO_AUTH] -s, --schema <NAME> Schemas to expose (repeatable or comma-separated) [default: public] [env: PGVIS_SCHEMAS] --mcp-http Also serve MCP at /mcp endpoint via Streamable HTTP --replica-dsn <DSN> Read replica DSNs (repeatable or comma-separated) [env: PGVIS_REPLICA_DSNS] --cache-enabled Enable the in-memory data cache [env: PGVIS_CACHE_ENABLED] --cache-ttl <SECS> Cache TTL in seconds [env: PGVIS_CACHE_TTL] --cache-max-entries <N> Maximum cache entries [env: PGVIS_CACHE_MAX_ENTRIES] --cache-lists Also cache list queries [env: PGVIS_CACHE_LISTS] --pubsub-enabled Enable pub/sub (LISTEN/NOTIFY) [env: PGVIS_PUBSUB_ENABLED] --pubsub-channel-prefix <P> Pub/sub channel prefix [env: PGVIS_PUBSUB_CHANNEL_PREFIX]serve refuses to start when neither jwt_secret nor anon_role is configured unless --insecure-no-auth is passed. It reloads the schema cache on SIGUSR1 (or NOTIFY pgrst, 'reload schema') and shuts down gracefully on SIGTERM/Ctrl-C.
pgvis mcp
Section titled “pgvis mcp”pgvis mcp [OPTIONS]
Options: -s, --schema <NAME> Schemas to expose [default: public] [env: PGVIS_SCHEMAS] --read-only Expose only read tools (no create/update/delete/RPC)pgvis openapi
Section titled “pgvis openapi”Prints the OpenAPI 3.0 JSON document to stdout and exits. Pipe to a file or tool:
pgvis --dsn "$PGVIS_DSN" openapi > openapi.jsonpgvis --dsn "$PGVIS_DSN" openapi | jq '.paths | keys'pgvis inspect
Section titled “pgvis inspect”Dumps the introspected schema cache as JSON — useful for debugging what pgvis sees:
pgvis --dsn "$PGVIS_DSN" inspect | jq '.tables | length'pgvis --dsn "$PGVIS_DSN" inspect | jq '.tables[0].columns[].name'DSN Format
Section titled “DSN Format”pgvis auto-detects the backend from the connection string:
| Pattern | Backend |
|---|---|
postgres://... or postgresql://... | PostgreSQL |
sqlite:./path.db or sqlite::memory: | SQLite |
file:path | SQLite |
*.db, *.sqlite, *.sqlite3 | SQLite |
| Anything else | PostgreSQL (default) |
PostgreSQL examples
Section titled “PostgreSQL examples”# Full URIpgvis --dsn "postgres://user:password@localhost:5432/mydb" serve
# Unix socketpgvis --dsn "postgres:///mydb?host=/var/run/postgresql" serve
# TLS required (certificate verified against the system trust store)pgvis --dsn "postgres://user:password@db.example.com/mydb?sslmode=require" serveTLS follows the DSN’s sslmode: disable, prefer (the default — TLS whenever the server offers it), or require. The server certificate is always verified against the platform trust store; set SSL_CERT_FILE to a CA bundle if your server’s CA isn’t in it. With prefer, a certificate that fails verification is a connection error — pgvis does not fall back to plaintext. verify-ca/verify-full and libpq’s sslrootcert are not supported. The password is redacted in pgvis’s logs.
SQLite examples
Section titled “SQLite examples”# File pathpgvis --dsn "sqlite:./data/app.db" serve --schema main --insecure-no-auth
# In-memory (for testing)pgvis --dsn "sqlite::memory:" serve --schema main --insecure-no-auth
# Bare file path (auto-detected by extension)pgvis --dsn "./mydata.sqlite3" serve --schema main --insecure-no-authSQLite tables live in the main schema, so pass --schema main: with the default public, the OpenAPI document and MCP tool list come out empty.
Next Steps
Section titled “Next Steps”- Quick Start — your first requests in 5 minutes
- Configuration Reference — all environment variables, TOML fields, and defaults