mcp-postgresql
A production-oriented MCP server that enables interaction with PostgreSQL databases, providing tools for query execution and schema introspection:
execute_query: Run any SQL statement (SELECT,INSERT,UPDATE,DELETE) and receive result rows or the affected row count.list_tables: Discover all tables in the current database, with an optional filter by schema name.describe_table: Inspect a table's full structure — column names, data types, nullability, default values, and primary key markers.list_databases: Retrieve all PostgreSQL databases available on the connected server.get_table_indexes: View all indexes on a specific table, including their definitions and uniqueness/primary key flags.get_foreign_keys: Discover all foreign key constraints on a table, including referenced target tables and columns.
Provides tools to execute SQL queries, list tables, describe table schemas, list databases, get table indexes, and foreign keys for a PostgreSQL database.
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., "@mcp-postgresqllist all tables in the public schema"
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.
MCP Server for PostgreSQL
Production-oriented MCP server for PostgreSQL, exposing database operations to MCP clients (Claude Desktop, VS Code Copilot, Cursor, and compatible hosts).
Features
Query execution (
SELECT,INSERT,UPDATE,DELETE)Database discovery and schema introspection
Table metadata inspection (columns, types, nullability, defaults, PK)
Index and foreign key discovery
Environment-driven configuration for secure deployment
Related MCP server: Azure Database for PostgreSQL MCP Server
Available Tools
Tool | Description |
| Executes a SQL statement and returns rows or affected row count |
| Lists tables from |
| Returns table column metadata and primary key markers |
| Lists all PostgreSQL databases |
| Lists table indexes with definitions and PK/unique flags |
| Lists table foreign keys and referenced targets |
Requirements
Node.js 18+
Access to a PostgreSQL instance
Network connectivity from MCP host to PostgreSQL (
host:port)
Configuration
Set connection settings using environment variables:
Variable | Required | Default | Description |
| No |
| PostgreSQL host or IP |
| No |
| PostgreSQL TCP port |
| No |
| Default database |
| Yes | — | Database user |
| Yes | — | Database password |
| No |
| Enables SSL/TLS |
| No |
| Max pool connections |
| No |
| Pool idle timeout (ms) |
| No |
| Transport mode: |
| No |
| Port for the HTTP server (only used when |
| No |
| Bind address for the HTTP server (only used when |
Usage
Run directly from GitHub
npx github:ferronicardoso/mcp-postgresqlClaude Code (CLI)
claude mcp add postgresql --scope user -- npx -y github:ferronicardoso/mcp-postgresql--scope controls where the server registration is stored:
Scope | Stored in | Visible to |
| project-local, untracked | only you, only in this project |
|
| anyone who clones the repo (commit it to share) |
| your global Claude Code config | you, across every project |
Environment variables can be passed with repeated --env KEY=VALUE flags before the --, e.g.:
Bash (Linux/macOS/WSL):
claude mcp add postgresql --scope user \
--env PGHOST=localhost \
--env PGPORT=5432 \
--env PGDATABASE=postgres \
--env PGUSER=postgres \
--env PGPASSWORD=your-password \
-- npx -y github:ferronicardoso/mcp-postgresqlPowerShell:
claude mcp add postgresql --scope user `
--env PGHOST=localhost `
--env PGPORT=5432 `
--env PGDATABASE=postgres `
--env PGUSER=postgres `
--env PGPASSWORD=your-password `
-- npx -y github:ferronicardoso/mcp-postgresqlCodex CLI
Bash (Linux/macOS/WSL):
codex mcp add postgresql \
--env PGHOST=localhost \
--env PGPORT=5432 \
--env PGDATABASE=postgres \
--env PGUSER=postgres \
--env PGPASSWORD=your-password \
npx -- -y github:ferronicardoso/mcp-postgresqlPowerShell:
codex mcp add postgresql `
--env PGHOST=localhost `
--env PGPORT=5432 `
--env PGDATABASE=postgres `
--env PGUSER=postgres `
--env PGPASSWORD=your-password `
npx -- -y github:ferronicardoso/mcp-postgresqlThis registers the server in ~/.codex/config.toml. To remove it, run codex mcp remove postgresql.
Claude Desktop configuration
%APPDATA%\\Claude\\claude_desktop_config.json:
{
"mcpServers": {
"postgresql": {
"command": "npx",
"args": ["github:ferronicardoso/mcp-postgresql"],
"env": {
"PGHOST": "localhost",
"PGPORT": "5432",
"PGDATABASE": "postgres",
"PGUSER": "postgres",
"PGPASSWORD": "your-password"
}
}
}
}VS Code MCP configuration
.vscode/mcp.json:
{
"servers": {
"postgresql": {
"command": "npx",
"args": ["github:ferronicardoso/mcp-postgresql"],
"env": {
"PGHOST": "localhost",
"PGPORT": "5432",
"PGDATABASE": "postgres",
"PGUSER": "postgres",
"PGPASSWORD": "your-password"
}
}
}
}Run with Docker (HTTP transport)
The published image runs in Streamable HTTP mode by default, for use as a remote MCP endpoint (e.g. from n8n's MCP Client Tool node or any Streamable HTTP-compatible client):
Bash (Linux/macOS/WSL):
docker run -d --name mcp-postgresql \
-p 3002:3002 \
-e PGHOST=host.docker.internal \
-e PGPORT=5432 \
-e PGDATABASE=postgres \
-e PGUSER=postgres \
-e PGPASSWORD=your-password \
ghcr.io/ferronicardoso/mcp-postgresql:latestPowerShell:
docker run -d --name mcp-postgresql `
-p 3002:3002 `
-e PGHOST=host.docker.internal `
-e PGPORT=5432 `
-e PGDATABASE=postgres `
-e PGUSER=postgres `
-e PGPASSWORD=your-password `
ghcr.io/ferronicardoso/mcp-postgresql:latestThe MCP endpoint is then available at http://localhost:3002/mcp.
Local Development
git clone https://github.com/ferronicardoso/mcp-postgresql
cd mcp-postgresql
npm install
npm run buildStart the compiled server:
npm startBuild and Commit Workflow
This repository intentionally tracks dist/ to support npx github:user/repo usage.
The project uses a Husky pre-commit hook to:
build TypeScript (
npm run build)stage generated artifacts (
git add dist)
Manual fallback:
npm run build
git add distSecurity Notes
Never commit real credentials or
.envfiles.Prefer least-privilege database users for production use.
For public or untrusted networks, enable encryption (
PGSSL=true) and configure certificates appropriately.
License
MIT © Raphael Augusto Ferroni Cardoso
Available Tools
6 toolsdescribe_tableA
Returns table structure: columns, types, nullability, defaults, and PK markers.
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | Table name | |
| schema | No | Table schema (default: public) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden. It clearly indicates a read operation ('Returns') with no destructive behavior, but lacks explicit mention of read-only nature, idempotency, or performance implications. Adequate but could be more explicit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that front-loads the purpose and includes specific output elements. Every word adds value, and there is no redundancy or unnecessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with two parameters and no output schema, the description sufficiently explains the return value and implies the parameters. It is complete given the tool's complexity and the context provided by sibling tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with both parameters documented. The description adds value by specifying the output's constituents (columns, types, etc.), which goes beyond the parameter descriptions. However, it does not elaborate on parameter usage or constraints beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function with a specific verb ('Returns') and resource ('table structure'), and lists the components (columns, types, nullability, defaults, PK markers). It distinguishes from siblings like get_foreign_keys and get_table_indexes by focusing on overall table structure.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives like execute_query or get_foreign_keys. The description does not include context about when it's appropriate or when to choose another sibling tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
execute_queryA
Executes a SQL query in PostgreSQL and returns rows or affected row count.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | SQL query to execute |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided; description does not disclose potential side effects (e.g., write operations), required permissions, or error behavior. Only minimally mentions return type.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single concise sentence, front-loaded with key action and result. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one parameter and no output schema, description covers the return type but lacks guidance on error handling, result size, or constraints, leaving agents underinformed for critical execution tasks.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents the parameter. Description adds no extra meaning beyond restating that the query is SQL.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the action (execute), the resource (SQL query in PostgreSQL), and the result (rows or affected row count). Distinguishes from sibling introspection tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies usage for arbitrary SQL execution but lacks explicit guidance on when to use vs alternatives, prerequisites, or safety warnings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_foreign_keysB
Lists foreign keys of a table and their referenced targets.
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | Table name | |
| schema | No | Table schema (default: public) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description must carry the full burden. It only states the basic function without disclosing any side effects, performance implications, or error behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that conveys the essential information without any unnecessary words or repetitions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the lack of annotations and output schema, the description is minimal but covers the core purpose. However, it omits details like return format and potential edge cases, leaving room for improvement.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for its two parameters, so the description adds no extra meaning. The baseline score of 3 is appropriate as it adequately documents parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists foreign keys of a table and includes the referenced targets, which is specific and distinct from sibling tools like describe_table or get_table_indexes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives like describe_table, which may also show foreign keys. The description lacks context for tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_table_indexesB
Lists indexes for a table with index definition and PK/uniqueness flags.
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | Table name | |
| schema | No | Table schema (default: public) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description must disclose behavioral traits. It only says it lists indexes with certain details, but does not mention read-only nature, permissions, side effects, or other important behaviors.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no wasted words. It is front-loaded with the main action. However, it could be slightly more informative without being wordy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity (2 params, no output schema), the description lacks completeness. It does not explain the return format, pagination, or that the schema defaults to public, leaving the agent with many unknowns.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the base is 3. The description adds no additional meaning beyond the schema's parameter descriptions (e.g., table name, schema with default).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists indexes for a table, with specific details about the output (index definition and PK/uniqueness flags). This differentiates it from sibling tools like describe_table or get_foreign_keys.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives (e.g., describe_table, get_foreign_keys) or when not to use it. The description simply states what it does without providing context for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_databasesA
Lists all PostgreSQL databases in the server.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description accurately states the tool's action but does not disclose any behavioral traits such as permission requirements, performance impact, or return value details. With no annotations, the description carries the full burden and provides only basic information.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that efficiently conveys the tool's purpose. It is concise without being verbose, though it could be slightly more informative.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (no parameters, no output schema, no annotations), the description provides sufficient context for an AI agent to understand its function. It could mention the listing scope but is otherwise complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has no parameters, and the description adds no additional semantics beyond the empty schema. This is appropriate for a parameterless tool, earning the baseline score of 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'lists' and the resource 'all PostgreSQL databases', which uniquely identifies the tool's function. It distinguishes from siblings like 'list_tables' by specifying the database level.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives like 'list_tables' or 'describe_table'. There are no conditions for usage or exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tablesB
Lists tables in the current database, optionally filtered by schema.
| Name | Required | Description | Default |
|---|---|---|---|
| schema | No | Schema to filter (default: all non-system schemas) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, and the description does not disclose behavioral traits like whether system tables are excluded by default or pagination behavior. The filtering behavior is implied but not elaborated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no wasted words. It is efficient but could benefit from slight expansion on default behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple listing tool with a single optional parameter, the description is adequate but does not indicate the return format or default schema behavior beyond the parameter description. It is minimally viable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (one parameter), and the description does not add extra meaning beyond the schema's description. The baseline of 3 is appropriate since the schema already documents the parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Lists' and the resource 'tables' with context 'in the current database' and optional schema filtering, distinguishing it from sibling tools like describe_table or execute_query.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives such as describe_table or list_databases. The description only mentions optional filtering without advising on use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool targets a distinct database operation: describe structure, run queries, list foreign keys, list indexes, list databases, and list tables. No overlap in functionality.
All tool names follow a consistent verb_noun pattern with underscores (e.g., describe_table, execute_query). No mixing of conventions.
With 6 tools, the set is well-scoped for a PostgreSQL server, covering essential schema exploration and query execution without being bloated.
Covers core introspection and querying, but lacks tools for DDL operations (create/alter/drop) or listing users/roles. Minor gap for power users.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Xata MCP server lets AI agents interact with your Xata projects, and Postgres database branches.
- SupabaseOAuthcom.supabase
MCP server for interacting with the Supabase platform
Hosted MCP server for PostgreSQL diagnostics: slow queries, missing indexes, connection pressure.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceAn extensible MCP server for database operations that supports PostgreSQL for managing schemas, tables, data, and user permissions. It features automatic migration recording for DDL changes and integrates with various AI-powered editors like Cursor, Zed, and Claude Code.372MIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol (MCP) Server that allows AI models to securely interact with data hosted in Azure Database for PostgreSQL. It enables natural language querying, schema exploration, and data management through MCP clients like Claude Desktop and Visual Studio Code.MIT
- AlicenseNot gradedqualityCmaintenanceA production-ready MCP server for PostgreSQL — built for Claude Desktop, Claude Code, and any MCP-compatible AI agent.Apache 2.0
- AlicenseNot gradedqualityCmaintenanceA Model Context Protocol (MCP) server that provides secure database access to PostgreSQL through Kysely ORM, enabling Claude Desktop to interact with PostgreSQL databases using natural language.181ISC
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/ferronicardoso/mcp-postgresql'
If you have feedback or need assistance with the MCP directory API, please join our Discord server