{"_id":"@iflow-mcp/zlash65-postgresql-ssh-mcp","name":"@iflow-mcp/zlash65-postgresql-ssh-mcp","dist-tags":{"latest":"1.2.1"},"versions":{"1.2.1":{"name":"@iflow-mcp/zlash65-postgresql-ssh-mcp","version":"1.2.1","description":"PostgreSQL MCP Server with built-in SSH tunneling for secure database access through bastion hosts","type":"module","main":"dist/index.js","types":"dist/index.d.ts","bin":{"iflow-mcp-zlash65-postgresql-ssh-mcp":"dist/index.js"},"scripts":{"build":"tsc && shx chmod +x dist/index.js dist/http.js","prepack":"npm run build","start":"node dist/index.js","start:http":"node --env-file=.env dist/http.js","dev":"tsc --watch","dev:http":"npx tsx src/http.ts","lint":"eslint src/**/*.ts","test":"vitest run","test:docker":"bash scripts/test-docker.sh","test:unit":"vitest run --dir tests/unit","clean":"shx rm -rf dist","typecheck":"tsc --noEmit"},"keywords":["mcp","model-context-protocol","modelcontextprotocol","postgresql","postgres","pg","sql","ssh","tunnel","ssh-tunnel","bastion","database","db","claude","chatgpt","json-rpc","jsonrpc","sse","streamable-http","oauth","auth0"],"author":"","license":"MIT","repository":{"type":"git","url":"git+https://github.com/Zlash65/postgresql-ssh-mcp.git"},"bugs":{"url":"https://github.com/Zlash65/postgresql-ssh-mcp/issues"},"homepage":"https://github.com/Zlash65/postgresql-ssh-mcp#readme","publishConfig":{"access":"public"},"dependencies":{"@modelcontextprotocol/sdk":"^1.25.1","cors":"^2.8.5","express":"^4.21.0","jose":"^5.9.0","pg":"^8.13.1","pg-connection-string":"^2.7.0","ssh2":"^1.16.0","zod":"^3.25.0"},"devDependencies":{"@eslint/js":"^9.39.2","@semantic-release/changelog":"^6.0.3","@semantic-release/git":"^10.0.1","@types/cors":"^2.8.17","@types/express":"^4.17.21","@types/node":"^22.10.2","@types/pg":"^8.11.10","@types/ssh2":"^1.15.1","@types/supertest":"^6.0.3","@typescript-eslint/eslint-plugin":"^8.18.0","@typescript-eslint/parser":"^8.18.0","conventional-changelog-conventionalcommits":"^8.0.0","eslint":"^9.17.0","globals":"^16.5.0","semantic-release":"^24.2.9","shx":"^0.3.4","supertest":"^7.1.4","typescript":"^5.7.2","vitest":"^2.1.8"},"engines":{"node":">=18.0.0"},"_id":"@iflow-mcp/zlash65-postgresql-ssh-mcp@1.2.1","_integrity":"sha512-iMtXePHQDb1GPqAwU30YA21PAtZ8Ta6ZiSppQ4dEyGjn4DOtuAWnlssBiib97I/hixq8HKD/xO8ZbU7cLRmz7w==","_resolved":"/app/auto-mcp-upload/data/21171/iflow-mcp-zlash65-postgresql-ssh-mcp-1.2.1.tgz","_from":"file:/app/auto-mcp-upload/data/21171/iflow-mcp-zlash65-postgresql-ssh-mcp-1.2.1.tgz","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-iMtXePHQDb1GPqAwU30YA21PAtZ8Ta6ZiSppQ4dEyGjn4DOtuAWnlssBiib97I/hixq8HKD/xO8ZbU7cLRmz7w==","shasum":"da098b2f75a50e7990b548451a5123e7264a8370","tarball":"https://registry.npmjs.org/@iflow-mcp/zlash65-postgresql-ssh-mcp/-/zlash65-postgresql-ssh-mcp-1.2.1.tgz","fileCount":75,"unpackedSize":250498,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCtqSPKv/yJhxjppkTRxVgB9trtB595fLIyTtkd2395mQIgLA1h4mqcrDkuW7c0woXlMU++Kwoq5m5LK0S/xBXYzIg="}]},"_npmUser":{"name":"chatflowdev","email":"chatflowdev@gmail.com"},"directories":{},"maintainers":[{"name":"chatflowdev","email":"chatflowdev@gmail.com"},{"name":"qystart","email":"987472953@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/zlash65-postgresql-ssh-mcp_1.2.1_1773193629286_0.9382685821385734"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-11T01:47:09.133Z","1.2.1":"2026-03-11T01:47:09.450Z","modified":"2026-03-11T01:47:09.776Z"},"maintainers":[{"name":"chatflowdev","email":"chatflowdev@gmail.com"},{"name":"qystart","email":"987472953@qq.com"}],"description":"PostgreSQL MCP Server with built-in SSH tunneling for secure database access through bastion hosts","homepage":"https://github.com/Zlash65/postgresql-ssh-mcp#readme","keywords":["mcp","model-context-protocol","modelcontextprotocol","postgresql","postgres","pg","sql","ssh","tunnel","ssh-tunnel","bastion","database","db","claude","chatgpt","json-rpc","jsonrpc","sse","streamable-http","oauth","auth0"],"repository":{"type":"git","url":"git+https://github.com/Zlash65/postgresql-ssh-mcp.git"},"bugs":{"url":"https://github.com/Zlash65/postgresql-ssh-mcp/issues"},"license":"MIT","readme":"# PostgreSQL SSH MCP Server\n\n[![npm version][npm-version-badge]][npm-package]\n[![npm downloads][npm-downloads-badge]][npm-package]\n[![license][license-badge]][license-link]\n\nA secure PostgreSQL MCP server with built-in SSH tunneling. Connect to databases through bastion hosts automatically — no manual `ssh -L` required.\n\n## Features\n\n- **Dual Transport** — STDIO for Claude Desktop, Streamable HTTP for ChatGPT\n- **SSH Tunneling** — Built-in tunnel with auto-reconnect and TOFU (trust on first use)\n- **Read-Only by Default** — Safe for production; enable writes explicitly\n- **OAuth Support** — Auth0 integration for secure ChatGPT connections\n- **Connection Pooling** — Efficient resource management with configurable limits\n\n---\n\n## Architecture\n\n![Architecture](assets/architecture.png)\n\n---\n\n## Quick Start\n\n### Claude Desktop (STDIO)\n\nAdd to your Claude Desktop config:\n\n| Platform | Config Location |\n|----------|-----------------|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%/Claude/claude_desktop_config.json` |\n\n```json\n{\n  \"mcpServers\": {\n    \"postgres\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@zlash65/postgresql-ssh-mcp\"],\n      \"env\": {\n        \"DATABASE_URI\": \"postgresql://user:password@localhost:5432/mydb\"\n      }\n    }\n  }\n}\n```\n\n### ChatGPT (Streamable HTTP)\n\n```bash\nDATABASE_URI=\"postgresql://user:pass@localhost:5432/mydb\" npx @zlash65/postgresql-ssh-mcp-http\n```\n\nThen configure ChatGPT to connect to `https://your-subdomain.example.com/mcp`.\n\n> **Note:** ChatGPT requires HTTPS. Use a tunnel (ngrok, Cloudflare Tunnel) for local testing.\n\n---\n\n## Available Tools\n\n### Query Tools\n\n| Tool | Description |\n|------|-------------|\n| `execute_query` | Execute SQL with parameterized queries. Results capped by `MAX_ROWS`. |\n| `explain_query` | Get EXPLAIN plans in text, JSON, YAML, or XML format. Supports ANALYZE. |\n\n### Schema Tools\n\n| Tool | Description |\n|------|-------------|\n| `list_schemas` | List database schemas. Excludes system schemas by default. |\n| `list_tables` | List tables with row counts and sizes. Optionally include views. |\n| `describe_table` | Get columns, constraints, and indexes for a table. |\n| `list_databases` | List all databases with owner, encoding, and size. |\n\n### Admin Tools\n\n| Tool | Description |\n|------|-------------|\n| `get_connection_status` | Get pool stats, tunnel state, and connection info. |\n| `list_active_connections` | Show active connections from `pg_stat_activity`. |\n| `list_long_running_queries` | Find queries running longer than a threshold. |\n| `get_database_version` | Get PostgreSQL server version. |\n| `get_database_size` | Get database size and largest tables. |\n| `get_table_stats` | Get vacuum/analyze stats and scan counts for a table. |\n\n---\n\n## Environment Variables\n\n### Database Connection\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `DATABASE_URI` | Yes* | — | Full connection string (e.g., `postgresql://user:pass@host:5432/db`) |\n| `DATABASE_HOST` | Yes* | — | Database hostname |\n| `DATABASE_PORT` | No | `5432` | Database port |\n| `DATABASE_NAME` | Yes* | — | Database name |\n| `DATABASE_USER` | Yes* | — | Database username |\n| `DATABASE_PASSWORD` | Yes* | — | Database password |\n\n*Either `DATABASE_URI` or all individual connection variables are required.\n\n### SSL Configuration\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `DATABASE_SSL` | Auto | `true` or `false`. Auto-enabled for non-localhost. |\n| `DATABASE_SSL_CA` | — | Path to CA certificate bundle |\n| `DATABASE_SSL_REJECT_UNAUTHORIZED` | `true` | Set `false` to allow self-signed certificates |\n\n### SSH Tunnel\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `SSH_ENABLED` | No | `false` | Set `true` to enable SSH tunneling |\n| `SSH_HOST` | Yes* | — | SSH server hostname |\n| `SSH_PORT` | No | `22` | SSH server port |\n| `SSH_USER` | Yes* | — | SSH username |\n| `SSH_PRIVATE_KEY_PATH` | Yes** | — | Path to private key file |\n| `SSH_PRIVATE_KEY_PASSPHRASE` | No | — | Passphrase for encrypted keys |\n| `SSH_PASSWORD` | Yes** | — | SSH password (alternative to key) |\n| `SSH_STRICT_HOST_KEY` | No | `true` | Verify host key against known_hosts |\n| `SSH_TRUST_ON_FIRST_USE` | No | `true` | Auto-add unknown hosts (when strict is enabled) |\n| `SSH_KNOWN_HOSTS_PATH` | No | `~/.ssh/known_hosts` | Custom known_hosts file |\n| `SSH_KEEPALIVE_INTERVAL` | No | `10000` | Keepalive interval in milliseconds |\n| `SSH_MAX_RECONNECT_ATTEMPTS` | No | `5` | Max reconnect attempts (`-1` for unlimited) |\n\n*Required when `SSH_ENABLED=true`\n**Either `SSH_PRIVATE_KEY_PATH` or `SSH_PASSWORD` is required\n\n### Query Behavior\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `READ_ONLY` | `true` | Block data modifications. Set `false` to allow writes. |\n| `MAX_ROWS` | `1000` | Maximum rows returned per query |\n| `QUERY_TIMEOUT` | `30000` | Query timeout in milliseconds |\n| `MAX_CONCURRENT_QUERIES` | `10` | Maximum concurrent queries |\n| `POOL_DRAIN_TIMEOUT_MS` | `5000` | Timeout for draining pool during reconnect |\n\n### HTTP Server (Streamable HTTP only)\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `PORT` | `3000` | HTTP server port |\n| `MCP_HOST` | `0.0.0.0` | HTTP server bind address |\n| `MCP_AUTH_MODE` | `none` | Authentication mode: `none` or `oauth` |\n| `MCP_STATELESS` | `true` | Stateless mode (each request re-initializes) |\n| `MCP_SERVER_POOL_SIZE` | `4` | Server instances for stateless mode |\n| `MCP_SESSION_TTL_MINUTES` | `30` | Session TTL for stateful mode |\n| `MCP_SESSION_CLEANUP_INTERVAL_MS` | `300000` | Session cleanup interval |\n| `MCP_ALLOWED_ORIGINS` | — | Comma-separated allowed CORS origins (`*` for any) |\n| `MCP_ALLOWED_HOSTS` | — | Comma-separated allowed Host headers |\n\n### OAuth (Auth0)\n\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `AUTH0_DOMAIN` | Yes* | Auth0 tenant domain (e.g., `tenant.us.auth0.com`) |\n| `AUTH0_AUDIENCE` | Yes* | Auth0 API identifier / audience |\n| `MCP_RESOURCE_DOCUMENTATION` | No | URL to API documentation (RFC 9728) |\n\n*Required when `MCP_AUTH_MODE=oauth`\n\n---\n\n## Documentation\n\n| Guide | Description |\n|-------|-------------|\n| [STDIO Setup](docs/stdio-setup.md) | Claude Desktop and local development |\n| [Streamable HTTP](docs/streamable-http.md) | HTTP server setup and configuration |\n| [Server Setup](docs/server-setup.md) | Deploy to production with nginx and SSL |\n| [ChatGPT Setup](docs/chatgpt-setup.md) | Complete Auth0 OAuth setup for ChatGPT |\n\n---\n\n## Docker\n\n### STDIO Server\n\n```bash\ndocker build --target runtime -t postgresql-mcp .\ndocker run -e DATABASE_URI=\"postgresql://...\" postgresql-mcp\n```\n\n### HTTP Server\n\n```bash\ndocker build --target runtime-http -t postgresql-mcp-http .\ndocker run -p 3000:3000 -e DATABASE_URI=\"postgresql://...\" postgresql-mcp-http\n```\n\n---\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Build\nnpm run build\n\n# Run tests\nnpm test\n\n# Type check\nnpm run typecheck\n\n# Lint\nnpm run lint\n```\n\n[npm-package]: https://www.npmjs.com/package/@zlash65/postgresql-ssh-mcp\n[npm-version-badge]: https://img.shields.io/npm/v/@zlash65/postgresql-ssh-mcp?color=2f6feb&label=npm\n[npm-downloads-badge]: https://img.shields.io/npm/dm/@zlash65/postgresql-ssh-mcp?color=2f6feb\n[license-badge]: https://img.shields.io/npm/l/@zlash65/postgresql-ssh-mcp?color=2f6feb\n[license-link]: LICENSE\n","readmeFilename":"README.md","_rev":"1-f926bd37e91840a2dc754cdda8c3f16e"}