@database-mcp/postgres
Advanced tools
+2
-2
| { | ||
| "name": "@database-mcp/postgres", | ||
| "version": "0.2.0", | ||
| "version": "0.3.0", | ||
| "description": "MCP server for PostgreSQL with read-only guardrails, row caps, and statement timeouts", | ||
@@ -33,3 +33,3 @@ "license": "MIT", | ||
| "dependencies": { | ||
| "@database-mcp/core": "^0.2.2", | ||
| "@database-mcp/core": "^0.3.0", | ||
| "pg": "^8.22.0" | ||
@@ -36,0 +36,0 @@ }, |
+77
-15
@@ -8,5 +8,2 @@ # @database-mcp/postgres | ||
| The password comes from the environment or a mounted secret file — never | ||
| from the client config: | ||
| ```json | ||
@@ -21,3 +18,3 @@ { | ||
| "POSTGRES_USER": "readonly_user", | ||
| "POSTGRES_PASSWORD": "...", | ||
| "POSTGRES_PASSWORD": "your-password", | ||
| "POSTGRES_DATABASE": "mydb" | ||
@@ -30,13 +27,78 @@ } | ||
| Alternatives: `DATABASE_URL=postgres://user@host:5432/db`, | ||
| `POSTGRES_PASSWORD_FILE=/run/secrets/...` (Docker/K8s-style), libpq's native | ||
| `PGHOST`/`PGUSER`/`PGPASSWORD`/`PGDATABASE`, or a YAML file via `--config` | ||
| (values support `${VAR}` expansion). `--print-config` shows the resolved | ||
| config with the password redacted. | ||
| ## Configuration | ||
| Use whichever method fits your setup. When methods are combined, flags win | ||
| over the YAML file, and the YAML file wins over environment variables. | ||
| ### Environment variables | ||
| `POSTGRES_HOST`, `POSTGRES_PORT`, `POSTGRES_USER`, `POSTGRES_PASSWORD`, | ||
| `POSTGRES_DATABASE`, as in the quick start above. The driver also honors | ||
| libpq's native `PGHOST`, `PGPORT`, `PGUSER`, `PGPASSWORD` and `PGDATABASE`, | ||
| so an existing psql environment works as-is. | ||
| ### DATABASE_URL | ||
| The convention most hosting platforms already give you: | ||
| ```json | ||
| "env": { "DATABASE_URL": "postgres://readonly_user@db.example.com:5432/mydb" } | ||
| ``` | ||
| Putting the password inside the URL works but is discouraged. If you do it | ||
| anyway, the server redacts it from any log output. | ||
| ### Mounted secret file (Docker, Kubernetes) | ||
| Keeps the password out of the environment and out of every config file. | ||
| Point `POSTGRES_PASSWORD_FILE` at a file that contains only the password: | ||
| ```json | ||
| "env": { | ||
| "POSTGRES_HOST": "127.0.0.1", | ||
| "POSTGRES_USER": "readonly_user", | ||
| "POSTGRES_PASSWORD_FILE": "/run/secrets/postgres_password", | ||
| "POSTGRES_DATABASE": "mydb" | ||
| } | ||
| ``` | ||
| ### YAML config file | ||
| Keeps the client entry down to two lines. Pass an absolute path, since the | ||
| working directory at launch is unpredictable: | ||
| ```json | ||
| "args": ["-y", "@database-mcp/postgres", "--config", "/absolute/path/database-mcp.yaml"] | ||
| ``` | ||
| ```yaml | ||
| # /absolute/path/database-mcp.yaml | ||
| connection: | ||
| host: 127.0.0.1 | ||
| port: 5432 | ||
| user: readonly_user | ||
| password: ${POSTGRES_PASSWORD} # expanded from the environment at load time | ||
| # or read it from a mounted file instead: | ||
| # password_file: /run/secrets/postgres_password | ||
| database: mydb | ||
| guardrails: | ||
| readOnly: true | ||
| maxRows: 1000 | ||
| queryTimeoutMs: 30000 | ||
| ``` | ||
| Never write a literal password into the YAML file. Use `${VAR}` expansion or | ||
| `password_file` as shown. | ||
| ### Checking the result | ||
| Run the server with `--print-config` to see exactly what it resolved. The | ||
| password always prints as `***`. | ||
| ## Tools | ||
| - **`execute_sql`** `{ sql }` — run a single SQL statement. | ||
| - **`search_objects`** `{ table? }` — list tables in the current schema, or | ||
| describe one (columns, indexes, foreign keys). | ||
| - **`execute_sql`** `{ sql }` runs a single SQL statement. | ||
| - **`search_objects`** `{ table? }` lists tables in the current schema, or | ||
| describes one (columns, indexes, foreign keys). | ||
@@ -52,5 +114,5 @@ ## Guardrails (defaults) | ||
| Read-only is enforced in two layers: a conservative SQL guard, plus | ||
| `default_transaction_read_only=on` on every pooled session — so writes | ||
| smuggled through CTEs (`WITH x AS (...) DELETE ...`) are rejected by | ||
| Postgres itself. | ||
| `default_transaction_read_only=on` on every pooled session. Writes smuggled | ||
| through CTEs, like `WITH x AS (...) DELETE ...`, are rejected by Postgres | ||
| itself. | ||
@@ -57,0 +119,0 @@ ## Part of database-mcp |
17256
10%123
101.64%+ Added
- Removed
Updated