postgresql-mcp
Allows connecting to Amazon RDS PostgreSQL instances and performing full database operations.
Enables authentication via Authentik as an OIDC identity provider for role-based access control.
Allows connecting to Google Cloud SQL PostgreSQL instances and performing database operations.
Enables authentication via Okta as an OIDC identity provider for role-based access control.
Provides comprehensive tools for interacting with any PostgreSQL database, including query execution, schema exploration, and database administration.
Allows connecting to Supabase PostgreSQL databases and performing database operations.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@postgresql-mcplist all tables with row counts"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
PostgreSQL MCP Server
A production-ready Model Context Protocol (MCP) server that connects AI assistants to any PostgreSQL database — cloud-hosted or self-hosted. Built on Cloudflare Workers and the Agents SDK, it provides 25 database tools with enterprise-grade authentication via Cloudflare Access and role-based access control through OIDC identity provider groups.
Key Features
Universal PostgreSQL compatibility — connects to Neon, Supabase, Amazon RDS, Google Cloud SQL, Azure Database, self-hosted instances, or any PostgreSQL-compatible database
25 database tools organized into 4 permission tiers (universal, read-only, read-write, admin)
Role-based access control — tools are conditionally registered per session based on IdP group membership
SQL safety layer — blocks dangerous operations (DROP DATABASE, privilege escalation, multi-statement injection) at the parser level
Enterprise SSO — OAuth 2.1 with PKCE via Cloudflare Access, supporting any OIDC identity provider (Okta, Authentik, Azure AD, etc.)
Connection pooling — Hyperdrive manages connection pooling and TCP proxying to your database
Private database support — reach databases on private networks via Cloudflare Tunnel
Serverless — runs on Cloudflare Workers with Durable Objects for per-user MCP sessions, no infrastructure to manage
Architecture
MCP Client (Claude, Cursor, Windsurf, etc.)
|
| Streamable HTTP + OAuth 2.1
v
Cloudflare Worker
|-- OAuthProvider --> Cloudflare Access --> OIDC IdP (Okta, Authentik, Azure AD, ...)
|-- McpAgent (Durable Object — one per authenticated session)
| |-- Role-based tool registration via IdP groups
| |-- SQL Safety Parser (blocks dangerous patterns)
| |-- Prompts (query assistant, schema explorer)
| |-- Resources (schema dump, health dashboard)
|-- pg-client --> Hyperdrive --> PostgreSQL
|
+-----------+-----------+
| |
Public databases Private databases
(Neon, Supabase, (via Cloudflare Tunnel
RDS, Cloud SQL) + VPC Service)Database Compatibility
This MCP server works with any PostgreSQL database that Hyperdrive can reach:
Database | Connection Method | Tunnel Required? |
Neon | Direct (public endpoint) | No |
Supabase | Direct (public endpoint) | No |
Amazon RDS (public) | Direct | No |
Amazon RDS (VPC) | Cloudflare Tunnel | Yes |
Google Cloud SQL | Direct or Tunnel | Depends on config |
Azure Database for PostgreSQL | Direct | No |
Self-hosted (public IP) | Direct | No |
Self-hosted (private network) | Cloudflare Tunnel | Yes |
Docker/local | Cloudflare Tunnel | Yes |
Role-Based Access Control
Tools are conditionally registered per MCP session based on the authenticated user's IdP groups. Users only see and can invoke tools matching their permission tier.
IdP Group | Tools Available | Count |
(any authenticated user) | Universal | 3 |
| Universal + Read-Only | 10 |
| Universal + Read-Only + Read-Write | 15 |
| All tools | 25 |
Groups are extracted from the groups claim in the OIDC ID token. Multiple group formats are supported (Authentik, Okta, comma-separated strings, arrays).
Tools Reference
Universal Tools (3) — Always Available
Tool | Description |
| Current user's email, name, groups, and computed access level |
| PostgreSQL version, database name, server time, current database user |
| MCP server and database connectivity check with response time |
Read-Only Tools (7) — Requires pg-readonly, pg-readwrite, or pg-admin
Tool | Description |
| List all tables, views, and materialized views with row counts and sizes |
| Full column definitions, indexes, and foreign key constraints |
| Execute validated read-only SQL (SELECT, WITH...SELECT) with parameterized values |
| EXPLAIN or EXPLAIN ANALYZE with JSON output for query optimization |
| Case-insensitive search across table and column names |
| Index listing with type, uniqueness, size, and scan count statistics |
| Live/dead row counts, dead row ratio, vacuum/analyze timestamps |
Read-Write Tools (5) — Requires pg-readwrite or pg-admin
Tool | Description |
| Parameterized INSERT with optional RETURNING clause |
| Parameterized UPDATE with WHERE clause (auto-adjusts parameter indices) |
| DELETE with mandatory confirmation flag as a safety check |
| Execute arbitrary non-DDL SQL (INSERT, UPDATE, DELETE, SELECT) |
| INSERT ... ON CONFLICT DO UPDATE with conflict target and update columns |
Admin Tools (10) — Requires pg-admin
Tool | Description |
| Connection utilization, buffer cache hit ratios, database size, uptime |
| Unused indexes, duplicate indexes, tables needing indexes |
| Dead row ratios, last vacuum timestamps, tables needing vacuum |
| Sequences approaching max value (prevents silent insert failures) |
| Create indexes (CONCURRENTLY by default for non-blocking operations) |
| Drop indexes (CONCURRENTLY by default) |
| Execute DDL statements (CREATE TABLE, ALTER TABLE, etc.) |
| Run ANALYZE to update query planner statistics |
| List running queries with duration, state, and wait events |
| Cancel a running query by PID |
Prompts (2) — Always Available
Prompt | Description |
| Generate accurate SQL from natural language using live schema context |
| Guided database overview with tables, relationships, and exploration suggestions |
Resources (2) — Always Available
Resource URI | Description |
| Full schema dump with tables, columns, types, and indexes (JSON) |
| Database health dashboard with connections, cache, and table stats (JSON) |
SQL Safety
A dedicated SQL parser validates every query before execution:
Always blocked (all roles):
DROP DATABASE,DROP ROLE,DROP USERCREATE ROLE,CREATE USER,ALTER ROLE,ALTER USERGRANT,REVOKECOPY TO/FROM PROGRAMMulti-statement injection (semicolons inside query body)
Role-enforced:
Read-only — only
SELECT,EXPLAIN,SHOW, and CTEs without mutationRead-write — adds
INSERT,UPDATE,DELETE(no DDL)Admin — adds DDL (
CREATE TABLE,ALTER TABLE,DROP TABLE, etc.)
Getting Started
Prerequisites
A Cloudflare account (Workers paid plan for Durable Objects)
Node.js 18+ and npm
Wrangler CLI (
npm install -g wrangler)A PostgreSQL database (any provider)
An OIDC identity provider configured in Cloudflare Access
Step 1: Clone and Install
git clone https://github.com/vnikhilbuddhavarapu/postgresql-mcp.git
cd postgresql-mcp
cp wrangler.jsonc.example wrangler.jsonc
npm installStep 2: Create Cloudflare Resources
KV Namespace (stores OAuth state):
wrangler kv namespace create OAUTH_KVCopy the id into wrangler.jsonc under kv_namespaces[0].id.
Hyperdrive Config (connection pooling):
# For a publicly reachable database:
wrangler hyperdrive create pg-mcp \
--connection-string="postgres://user:password@host:5432/dbname"
# For a private database via Cloudflare Tunnel:
# First create a VPC Service, then:
wrangler hyperdrive create pg-mcp \
--connection-string="postgres://user:password@<PRIVATE_IP>:5432/dbname" \
--vpc-id="<VPC_SERVICE_ID>"Copy the Hyperdrive id into wrangler.jsonc under hyperdrive[0].id.
Step 3: Configure Cloudflare Access (OIDC)
Go to Cloudflare Zero Trust > Access > Applications > Add SaaS Application
Choose OIDC and select your identity provider
Set the Redirect URI to
https://<your-worker>.workers.dev/callbackEnable scopes:
openid,email,profile,groupsNote down the following from the application configuration:
Client ID
Client Secret
Token Endpoint
Authorization Endpoint
JWKS/Key Endpoint
Configure your IdP to include a
groupsclaim with values:pg-readonly,pg-readwrite, and/orpg-admin
Step 4: Set Secrets
cp .dev.vars.example .dev.vars
# Edit .dev.vars with your Access credentialsStep 5: Deploy
# Generate types
wrangler types
# Deploy
wrangler deploy
# Push secrets to production
wrangler secret bulk .dev.varsStep 6: Connect an MCP Client
Use the MCP endpoint URL with any compatible client:
https://<your-worker>.workers.dev/mcpOr test with the MCP Inspector:
npx @modelcontextprotocol/inspector
# Enter your /mcp URL, authenticate via the OAuth flowDevelopment
npm install # Install dependencies
wrangler types # Generate TypeScript types from bindings
npm run type-check # TypeScript type checking
npm test # Run Vitest unit tests (48 tests)
npm run lint # Lint with oxlint
npm run format # Format with oxfmt
wrangler dev # Local development server (note: Hyperdrive requires deploy for full testing)
wrangler deploy # Deploy to CloudflareProject Structure
postgresql-mcp/
├── src/
│ ├── index.ts # McpAgent (Durable Object) + OAuthProvider entry point
│ ├── env.d.ts # Environment type declarations
│ ├── auth/
│ │ ├── access-handler.ts # OAuth /authorize + /callback flow with Cloudflare Access
│ │ └── workers-oauth-utils.ts # CSRF, PKCE, state management, token exchange
│ ├── db/
│ │ ├── pg-client.ts # PostgreSQL client wrapper (Hyperdrive connection pooling)
│ │ ├── sql-parser.ts # SQL classification and safety validation
│ │ └── schemas.ts # Zod schemas for all tool inputs and database types
│ ├── tools/
│ │ ├── universal.ts # 3 tools — userInfo, connectionInfo, healthCheck
│ │ ├── readonly.ts # 7 tools — listTables, describeTable, executeQuery, ...
│ │ ├── readwrite.ts # 5 tools — insertRows, updateRows, deleteRows, ...
│ │ └── admin.ts # 10 tools — databaseHealth, createIndex, executeDDL, ...
│ ├── prompts/
│ │ ├── query-assistant.ts # Natural language to SQL with live schema context
│ │ └── schema-explorer.ts # Guided database exploration
│ └── resources/
│ ├── schema.ts # schema://tables — full schema dump
│ └── health.ts # health://overview — database health dashboard
├── tests/
│ └── sql-parser.test.ts # 48 unit tests for SQL safety parser
├── .dev.vars.example # Template for environment secrets
├── wrangler.jsonc.example # Template for Worker configuration (copy to wrangler.jsonc)
├── tsconfig.json # TypeScript configuration
└── package.json # Dependencies and scriptsTech Stack
Runtime: Cloudflare Workers + Durable Objects
MCP SDK: Agents SDK (
McpAgent) +@modelcontextprotocol/sdkAuthentication:
@cloudflare/workers-oauth-provider+ Cloudflare Access (Generic OIDC SaaS)Database: Hyperdrive +
pgdriverValidation: Zod v4
Testing: Vitest
Related Documentation
License
MIT
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/vnikhilbuddhavarapu/postgresql-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server