postgres-ssh-mcp
A cross-platform MCP server for querying and introspecting PostgreSQL databases with SSH tunnel support, featuring multi-layered query safety and read-only enforcement.
README
postgres-ssh-mcp
Cross-platform MCP server for PostgreSQL with SSH tunnel support. Works on macOS, Linux, and Windows.
Overview
postgres-ssh-mcp exposes MCP tools that allow AI tools to query and introspect PostgreSQL databases. It supports three connection modes:
Connection Modes
| Mode | When it activates | How it connects |
|---|---|---|
| Direct | No SSH vars set | Connects to Postgres directly (no tunnel) |
| SSH config | SSH_HOST is set |
Reads ~/.ssh/config for the given alias; uses its HostName, User, IdentityFile, etc. |
| Explicit SSH | SSH_HOSTNAME + SSH_USER are set |
Opens an SSH tunnel using the values from environment variables |
Using with AI Tools
Any MCP-Compatible Tool
Tools such as Claude Desktop, Cursor, and Windsurf use a JSON config file. Add an entry under mcpServers:
{
"mcpServers": {
"postgres-ssh-mcp": {
"command": "npx",
"args": ["-y", "postgres-ssh-mcp"],
"env": {
"DB_HOST": "localhost",
"DB_NAME": "mydb",
"DB_USER": "dbuser",
"DB_PASSWORD": "dbpassword",
// If you have an SSH config alias:
"SSH_HOST": "my-bastion",
// Or if you need explicit SSH:
"SSH_HOSTNAME": "127.0.0.1",
"SSH_USER": "mybastionuser",
"SSH_IDENTITY_FILE": "~/.ssh/mybastionkey", // optional if you use the default key path
"SSH_KEY_PASSPHRASE": "mypassphrase", // optional, if your private key is encrypted
"SSH_PORT": "1234", // defaults to 22
}
}
}
}
For SSH tunnel connections, add SSH_HOST (SSH config alias) or SSH_HOSTNAME + SSH_USER (explicit credentials) to the env block.
Claude Code
Use claude mcp add to register the server. All environment variables must be passed via --env flags.
claude mcp add --transport stdio postgres-ssh-mcp \
--env DB_HOST=localhost \
--env DB_NAME=mydb \
--env DB_USER=dbuser \
--env DB_PASSWORD=dbpassword \
-- npx -y postgres-ssh-mcp
Hint: You can include --scope project to add the server only to the current project.
Tools
| Tool | Description |
|---|---|
run_query |
Execute a SQL query (read-only by default; see DB_READ_ONLY). Supports parameterized queries with $1, $2, ... placeholders |
explain_query |
Get the execution plan for a SQL query. Supports all PostgreSQL EXPLAIN options (ANALYZE, BUFFERS, TIMING, etc) and output formats (text, JSON, YAML, XML) |
list_schemas |
List all schemas in the database |
list_tables |
List tables in a schema (default: public) |
describe_table |
Show columns, types, and nullability for a table |
get_connection_status |
Show connection pool stats, database version, size, and server configuration |
Defense-in-Depth Query Safety
This is the key feature that sets postgres-ssh-mcp apart from other PostgreSQL MCP servers. It is the only one that enforces multi-layered protection against unintended data modifications through a combination of safety mechanisms.
- AST-level SQL validation using
pgsql-parserand@pgsql/traverse— parses SQL into an abstract syntax tree and walks it to detect mutations, including hidden ones in CTEs,SELECT INTO, and locking clauses. OnlySELECTandEXPLAINstatements are allowed. - Dangerous function denylist — blocks 250+ PostgreSQL functions that can cause side effects even inside read-only transactions, including
pg_sleep,nextval,pg_notify, file I/O functions, advisory locks, and replication controls. - Read-only transaction wrapping — all queries execute inside
BEGIN TRANSACTION READ ONLYwith automaticROLLBACK. - Single-statement enforcement — multi-statement queries are rejected before execution.
Note: Disabling these safety mechanisms is not recommended, however, you can do so by setting DB_READ_ONLY=false, which grants AI tools full write access to the database.
Environment Variables
These are all environment variables that can be used to configure this MCP server.
Required
| Variable | Description |
|---|---|
DB_HOST |
Postgres host or RDS endpoint |
DB_NAME |
Database name |
DB_USER |
Database user |
DB_PASSWORD |
Database password |
Optional
| Variable | Default | Description |
|---|---|---|
ALLOWED_TOOLS |
(all) | Comma-separated list of tools to register. When unset, all tools are available. Case-sensitive. Example: run_query,describe_table |
DB_PORT |
5432 |
Postgres port |
DB_READ_ONLY |
true |
Set to false to allow write queries (run_query only) |
DB_SSL |
false |
Set to true to enable TLS for the database connection |
DB_SSL_CA |
— | Path to a custom CA certificate file (PEM) for SSL verification |
DB_SSL_REJECT_UNAUTHORIZED |
true |
Set to false to skip SSL certificate validation (insecure) |
DB_MAX_ROWS |
1000 |
Maximum rows returned per query. Uses cursor-based fetching in read-only mode |
DB_CONNECTION_POOL_SIZE |
5 |
Maximum number of connections in the pool |
DB_CONNECTION_TIMEOUT_MS |
10000 |
Milliseconds to wait for a connection from the pool |
DB_QUERY_TIMEOUT_MS |
15000 |
Milliseconds before a query is forcibly cancelled |
DB_POOL_DRAIN_TIMEOUT_MS |
5000 |
Milliseconds to wait for old pool to drain during reconnection (0 to never wait) |
SSH_HOST |
— | SSH config alias (reads ~/.ssh/config) |
SSH_HOSTNAME |
— | Bastion hostname or IP |
SSH_USER |
— | SSH login user |
SSH_PORT |
22 |
SSH port |
SSH_STRICT_HOST_KEY_CHECKING |
true |
Enables or disables strict host checking |
SSH_IDENTITY_FILE |
— | Absolute path or ~/... to private key file |
SSH_KEY_PASSPHRASE |
— | Passphrase for an encrypted private key |
SSH_PASSWORD |
— | SSH password (alternative to key-based auth) |
SSH_KEEPALIVE_INTERVAL_MS |
disabled | Milliseconds between SSH keepalive probes (if set: minimum 1000) |
SSH_KEEPALIVE_COUNT_MAX |
3 |
Max unanswered keepalive probes before dropping the connection |
SSH_TRUST_ON_FIRST_USE |
true |
Auto-accept and save unknown SSH host keys on first connection |
SSH_KNOWN_HOSTS_PATH |
— | Path to custom known_hosts file (default: ~/.ssh/known_hosts) |
SSH_MAX_RECONNECT_ATTEMPTS |
5 |
Max SSH reconnection attempts (-1 for unlimited, 0 to disable) |
Development
Copy the example env file and fill in your values:
git clone https://github.com/SecretX33/postgres-ssh-mcp.git
cd postgres-ssh-mcp
npm install
npm run build
The compiled server is written to dist/index.js.
Copy the example env file and fill in your values:
cp .env.example .env
# edit .env
Then run in watch mode (automatically loads .env):
npm run dev
License
MIT
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。