@futuretea/postgres-mcp-server 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +50 -7
  2. package/package.json +6 -6
package/README.md CHANGED
@@ -6,10 +6,15 @@ An MCP (Model Context Protocol) server for discovering one PostgreSQL 17+ instan
6
6
 
7
7
  ## Quick start
8
8
 
9
- Set a connection target for a minimally privileged PostgreSQL role, then build and inspect the catalog:
9
+ Set discrete connection fields for a minimally privileged PostgreSQL role, then build and inspect the catalog. A valid UTF-8 password is a normal environment value here and does not need URL encoding. A password that is not valid UTF-8 is rejected before connect, and the error does not include the password.
10
10
 
11
11
  ```sh
12
- export DATABASE_URL='postgres://reader@127.0.0.1:5432/app?sslmode=disable'
12
+ export MCP_POSTGRES_HOST=127.0.0.1
13
+ export MCP_POSTGRES_PORT=5432
14
+ export MCP_POSTGRES_DATABASE=app
15
+ export MCP_POSTGRES_USERNAME=reader
16
+ export MCP_POSTGRES_PASSWORD='<runtime-secret>'
17
+ export MCP_POSTGRES_SSLMODE=disable
13
18
  make build
14
19
  ./bin/postgres-mcp-server tools list
15
20
  ./bin/postgres-mcp-server mcp
@@ -59,7 +64,7 @@ docker run --rm -i \
59
64
  ghcr.io/futuretea/postgres-mcp-server:v0.0.1
60
65
  ```
61
66
 
62
- For an MCP client that launches Docker, pass the connection setting through the Docker process:
67
+ For an MCP client that launches Docker, pass the connection settings through the Docker process:
63
68
 
64
69
  ```json
65
70
  {
@@ -124,7 +129,38 @@ Every successful tool response is one JSON text envelope with `schema_version`,
124
129
 
125
130
  ## Database connection
126
131
 
127
- Use a bare `DATABASE_URL`, or standard PostgreSQL environment variables such as `PGHOST`, `PGPORT`, `PGDATABASE`, `PGUSER`, `PGPASSWORD`, and `PGSSLMODE`. When `DATABASE_URL` is set it takes precedence. Configuration must resolve to one `host:port`; distinct URL or comma-separated `PGHOST` targets are rejected before a connection is created.
132
+ Set discrete environment variables. Do not put the host, password, or a connection URL in YAML. A valid UTF-8 password does not need URL encoding.
133
+
134
+ | Variable | libpq alias | Required without `DATABASE_URL` or `PGSERVICE` | Default |
135
+ |---|---|---|---|
136
+ | `MCP_POSTGRES_HOST` | `PGHOST` | yes | none |
137
+ | `MCP_POSTGRES_PORT` | `PGPORT` | no | `5432` |
138
+ | `MCP_POSTGRES_DATABASE` | `PGDATABASE` | yes | none |
139
+ | `MCP_POSTGRES_USERNAME` | `PGUSER` | yes | none |
140
+ | `MCP_POSTGRES_PASSWORD` | `PGPASSWORD` | no | empty |
141
+ | `MCP_POSTGRES_SSLMODE` | `PGSSLMODE` | no | `prefer` |
142
+
143
+ `MCP_POSTGRES_*` matches this server's `MCP_` environment prefix and the ClickHouse server's `MCP_CLICKHOUSE_*` connection fields (`MCP_CLICKHOUSE_DATABASE`, `MCP_CLICKHOUSE_USERNAME`, `MCP_CLICKHOUSE_PASSWORD`). MySQL uses `MYSQL_MCP_*` because that repository prefixes every variable, including its HTTP port, with `MYSQL_MCP_`. `MCP_POSTGRES_PORT` is the database port. The HTTP port remains `MCP_PORT`.
144
+
145
+ Each `MCP_POSTGRES_*` variable is an alias of the `PG*` variable in the same row. If both names are set to different values, startup fails. The error names the two variables and does not print their values. `MCP_POSTGRES_*` is an explicit connection parameter, so it overrides a `PGSERVICE` entry for that field. When the `MCP_POSTGRES_*` alias is unset, a service file still overrides `PG*`, which is pgx's existing libpq behavior.
146
+
147
+ An unset `MCP_POSTGRES_PASSWORD` leaves `PGPASSWORD` and `.pgpass` in place. An empty `PGPASSWORD` is unset, matching libpq. Setting `MCP_POSTGRES_PASSWORD` to an empty string is an explicit empty password: it overrides `PGPASSWORD` and `.pgpass`. If that empty value and a non-empty `PGPASSWORD` are both set, startup fails and the error names the two variables without printing them.
148
+
149
+ The resolved password must be valid UTF-8. This applies to `MCP_POSTGRES_PASSWORD`, `PGPASSWORD`, a `DATABASE_URL` password, a service-file password, and a `.pgpass` password. Invalid UTF-8 fails configuration with `[postgres_invalid_config] password must be valid UTF-8` and the value is not printed. Keeping the original bytes in the connection config is not authentication: pgx's SCRAM preparation replaces those bytes with U+FFFD and would send a different password.
150
+
151
+ `PGSERVICE` can supply the required fields from a PostgreSQL service file. Without `DATABASE_URL` or `PGSERVICE`, host, database, and username are required. Libpq defaults for those three fields are not used, so a partial `PG*` setup that omits one of them fails. A missing required field produces an error that names the absent variables, for example `[postgres_invalid_config] missing MCP_POSTGRES_HOST or PGHOST, MCP_POSTGRES_DATABASE or PGDATABASE, MCP_POSTGRES_USERNAME or PGUSER`.
152
+
153
+ Configuration must resolve to one `host:port`. Distinct URL targets or comma-separated hosts are rejected before a connection is created.
154
+
155
+ ### `DATABASE_URL` (optional)
156
+
157
+ `DATABASE_URL` remains an advanced alternative for a libpq URL you already have. When it is set, that URL is the connection string and every `MCP_POSTGRES_*` variable is ignored. Standard `PG*` variables still fill settings the URL omits, and a setting present in the URL overrides the same `PG*` variable. Leave `DATABASE_URL` unset to use the discrete fields above.
158
+
159
+ ```sh
160
+ export DATABASE_URL='postgres://reader@127.0.0.1:5432/app?sslmode=disable'
161
+ ```
162
+
163
+ A password in `DATABASE_URL` must be URL-encoded. Prefer `MCP_POSTGRES_PASSWORD` when the password contains reserved characters.
128
164
 
129
165
  At startup the server requires PostgreSQL 17 or newer and rejects service roles that are superusers, bypass row-level security, have replication, or belong to server-file, server-program, or backend-signalling roles. Use a dedicated, least-privilege database role.
130
166
 
@@ -149,7 +185,7 @@ GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_reader;
149
185
 
150
186
  ### Verify effective schema privileges
151
187
 
152
- Before configuring `DATABASE_URL`, verify that `mcp_reader` cannot create objects in the target schema:
188
+ Before configuring the connection, verify that `mcp_reader` cannot create objects in the target schema:
153
189
 
154
190
  ```sql
155
191
  SELECT has_schema_privilege('mcp_reader', 'public', 'CREATE') AS can_create_objects;
@@ -164,7 +200,7 @@ ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public
164
200
  GRANT SELECT ON TABLES TO mcp_reader;
165
201
  ```
166
202
 
167
- Before configuring `DATABASE_URL`, connect as `mcp_reader` and verify that every boolean below is `false`:
203
+ Before configuring the connection, connect as `mcp_reader` and verify that every boolean below is `false`:
168
204
 
169
205
  ```sql
170
206
  SELECT current_user, rolsuper, rolbypassrls, rolreplication,
@@ -217,7 +253,14 @@ The HTTP health endpoint is `GET /healthz`. See `config.example.yaml` for transp
217
253
 
218
254
  ```sh
219
255
  make docker
220
- docker run --rm -i --env DATABASE_URL postgres-mcp-server:dev
256
+ docker run --rm -i \
257
+ --env MCP_POSTGRES_HOST \
258
+ --env MCP_POSTGRES_PORT \
259
+ --env MCP_POSTGRES_DATABASE \
260
+ --env MCP_POSTGRES_USERNAME \
261
+ --env MCP_POSTGRES_PASSWORD \
262
+ --env MCP_POSTGRES_SSLMODE \
263
+ postgres-mcp-server:dev
221
264
  ```
222
265
 
223
266
  The image entrypoint is `postgres-mcp-server mcp`.
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@futuretea/postgres-mcp-server",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Read-only PostgreSQL Model Context Protocol server",
5
5
  "main": "./bin/index.js",
6
6
  "bin": {
7
7
  "postgres-mcp-server": "bin/index.js"
8
8
  },
9
9
  "optionalDependencies": {
10
- "@futuretea/postgres-mcp-server-darwin-amd64": "0.1.0",
11
- "@futuretea/postgres-mcp-server-darwin-arm64": "0.1.0",
12
- "@futuretea/postgres-mcp-server-linux-amd64": "0.1.0",
13
- "@futuretea/postgres-mcp-server-linux-arm64": "0.1.0",
14
- "@futuretea/postgres-mcp-server-windows-amd64": "0.1.0"
10
+ "@futuretea/postgres-mcp-server-darwin-amd64": "0.2.0",
11
+ "@futuretea/postgres-mcp-server-darwin-arm64": "0.2.0",
12
+ "@futuretea/postgres-mcp-server-linux-amd64": "0.2.0",
13
+ "@futuretea/postgres-mcp-server-linux-arm64": "0.2.0",
14
+ "@futuretea/postgres-mcp-server-windows-amd64": "0.2.0"
15
15
  },
16
16
  "repository": {
17
17
  "type": "git",