@yawlabs/postgres-mcp 0.8.0 → 0.9.1
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.
- package/CHANGELOG.md +94 -5
- package/README.md +42 -1
- package/bin/postgres-mcp.mjs +167 -0
- package/dist/index.js +1 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,11 +7,74 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
## [0.9.1] - 2026-08-07
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **Corrected the runtime startup figures published in 0.9.0.** They were wrong
|
|
15
|
+
in both magnitude and direction, and the README used them to advise opting
|
|
16
|
+
out of the faster runtime.
|
|
17
|
+
|
|
18
|
+
The 0.9.0 numbers (Node ~650-900ms, oam ~980-1290ms, launcher-to-oam ~1.8s)
|
|
19
|
+
were measured against cold, freshly-built binaries. On Windows a binary that
|
|
20
|
+
is not in the on-access scanner's cache is rescanned on every exec, while
|
|
21
|
+
`node` resolved from PATH was cached long ago -- so the comparison measured
|
|
22
|
+
the scanner and put the entire penalty on the binary under test.
|
|
23
|
+
|
|
24
|
+
Re-measured on the same hardware with every binary warmed first, mean of 12
|
|
25
|
+
runs, `postgres-mcp version` (full module init):
|
|
26
|
+
|
|
27
|
+
| path | startup |
|
|
28
|
+
|---|---|
|
|
29
|
+
| standalone binary (`oam compile`) | 298ms |
|
|
30
|
+
| `oam run dist/index.js` | 306ms |
|
|
31
|
+
| `node dist/index.js` | 358ms |
|
|
32
|
+
| launcher -> Node (in-process) | 370ms |
|
|
33
|
+
| launcher -> oam (spawn) | 409ms |
|
|
34
|
+
|
|
35
|
+
oam starts faster than Node. What the launcher costs is the spawn: reaching
|
|
36
|
+
oam means Node has already booted, and that ~100ms hop outweighs oam's ~52ms
|
|
37
|
+
advantage, so the two land within ~40ms of each other through the npm `bin`.
|
|
38
|
+
`POSTGRES_MCP_RUNTIME=node` remains available but is now a marginal
|
|
39
|
+
difference, not the meaningful one 0.9.0 described.
|
|
40
|
+
|
|
41
|
+
No behavior changed -- `auto` (prefer oam) was and remains the default, and
|
|
42
|
+
it was the right default for the wrong stated reason. README, CHANGELOG, and
|
|
43
|
+
the launcher's header comment are corrected; the launcher comment also
|
|
44
|
+
records the measurement trap so the mistake is not repeated.
|
|
45
|
+
|
|
46
|
+
## [0.9.0] - 2026-08-07
|
|
47
|
+
|
|
48
|
+
### Added
|
|
49
|
+
|
|
50
|
+
- The `postgres-mcp` command is now a runtime launcher (`bin/postgres-mcp.mjs`)
|
|
51
|
+
that prefers the [oam](https://oamjs.org) runtime and falls back to Node.
|
|
52
|
+
Selection is via `POSTGRES_MCP_RUNTIME` (`auto` | `oam` | `node`, default
|
|
53
|
+
`auto`) and `OAM_BIN`.
|
|
54
|
+
|
|
55
|
+
The fallback costs nothing: npm already started Node to run the launcher, so
|
|
56
|
+
falling back is an `import()` into that same process -- no second spawn, no
|
|
57
|
+
extra startup, behavior identical to running `dist/index.js` directly. Users
|
|
58
|
+
without oam see no change and no stderr noise.
|
|
59
|
+
|
|
60
|
+
Equivalence on the oam path is verified end to end, not assumed: all 21 tools
|
|
61
|
+
register, a live query returns identical rows and `dataTypeName` values, and
|
|
62
|
+
the error paths match. oam provides every `node:` builtin the pg driver needs
|
|
63
|
+
(`net`, `tls`, `crypto`, `dns`), so SCRAM auth and the extended query protocol
|
|
64
|
+
both work.
|
|
65
|
+
|
|
66
|
+
**Latency, stated plainly:** taking the oam path means Node has booted first,
|
|
67
|
+
so both startups are paid. On windows-arm64 against the 1.4 MB bundle, Node
|
|
68
|
+
alone is ~650-900ms, oam alone ~980-1290ms, and launcher-to-oam ~1.8s. That is
|
|
69
|
+
a one-time cost per MCP session rather than per tool call, but it is a real
|
|
70
|
+
regression against plain Node -- `POSTGRES_MCP_RUNTIME=node` opts out.
|
|
71
|
+
|
|
72
|
+
> **These figures are wrong. See 0.9.1.** They were measured against cold,
|
|
73
|
+
> freshly-built binaries and reflect the Windows on-access virus scanner, not
|
|
74
|
+
> either runtime. oam is in fact faster than Node here. Left in place rather
|
|
75
|
+
> than rewritten so the correction has something to point at.
|
|
76
|
+
|
|
77
|
+
## [0.8.0] - 2026-08-07
|
|
15
78
|
|
|
16
79
|
### Changed (breaking)
|
|
17
80
|
|
|
@@ -106,6 +169,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
106
169
|
(PG17), and with only 17/18 in the matrix the pre-1.11 branch was never
|
|
107
170
|
selected.
|
|
108
171
|
|
|
172
|
+
## [0.7.0] - 2026-07-21
|
|
173
|
+
|
|
174
|
+
Backfilled from `git log v0.6.20..v0.7.0` -- this release shipped without a
|
|
175
|
+
CHANGELOG entry. Summarized from commit subjects rather than re-derived from
|
|
176
|
+
the diff, so it is less detailed than the entries around it.
|
|
177
|
+
|
|
178
|
+
### Added
|
|
179
|
+
|
|
180
|
+
- `pg_table_bloat`: `approx` and `exact` methods via `pgstattuple` (#19).
|
|
181
|
+
- `pg_top_queries`: `io_read_time_ms` / `io_write_time_ms` on
|
|
182
|
+
`pg_stat_statements` >= 1.10 (#16).
|
|
183
|
+
- Cross-platform single-binary release pipeline (Scoop + Homebrew), released
|
|
184
|
+
as 0.6.21.
|
|
185
|
+
|
|
186
|
+
### Fixed
|
|
187
|
+
|
|
188
|
+
- `pg_list_tables`: cast `reltuples` to `float8` so `estimated_rows` is a
|
|
189
|
+
number rather than a string (#17).
|
|
190
|
+
- 10 confirmed findings from a review of `f7b7cb3..a736200` (#21).
|
|
191
|
+
|
|
192
|
+
### Removed
|
|
193
|
+
|
|
194
|
+
- GitHub Actions workflows and the dependabot config (#24). This is why the
|
|
195
|
+
repo has no `.github/` directory and why `release.sh` is the only release
|
|
196
|
+
path; several stale comments referring to CI survived until 0.8.0.
|
|
197
|
+
|
|
109
198
|
## [0.6.20] - 2026-06-04
|
|
110
199
|
|
|
111
200
|
### Fixed
|
package/README.md
CHANGED
|
@@ -198,10 +198,51 @@ All env vars are read from the MCP server's environment:
|
|
|
198
198
|
| `POSTGRES_MAX_ROWS` | `1000` | Cap on rows returned by `pg_query`. |
|
|
199
199
|
| `POSTGRES_POOL_MAX` | `5` | Max pool connections. Set to `1` for single-threaded backends (pglite-socket, PgBouncer transaction mode). |
|
|
200
200
|
| `POSTGRES_SSL_REJECT_UNAUTHORIZED` | unset | Set to `false` to skip TLS cert verification (for managed DBs using private-CA certs). Connection is still encrypted. |
|
|
201
|
+
| `POSTGRES_MCP_RUNTIME` | `auto` | Which JS runtime executes the server: `auto` (prefer [oam](https://oamjs.org), fall back to Node), `oam` (require oam, fail if absent), `node` (never use oam). See [Runtime](#runtime). |
|
|
202
|
+
| `OAM_BIN` | unset | Explicit path to an `oam` binary, checked before PATH and the default install locations. |
|
|
201
203
|
|
|
202
204
|
### Supported Postgres versions
|
|
203
205
|
|
|
204
|
-
Tested on **PostgreSQL 17 and 18** in
|
|
206
|
+
Tested on **PostgreSQL 15, 17 and 18** in the integration matrix. Should work on PG13+ -- a few tools (`pg_replication_status` reading `wal_status`, `pg_top_queries` reading `*_exec_time`) rely on columns that landed in PG13. PG12 and below are out of upstream support and not exercised here.
|
|
207
|
+
|
|
208
|
+
### Runtime
|
|
209
|
+
|
|
210
|
+
The published `postgres-mcp` command is a small launcher that prefers the [oam](https://oamjs.org) runtime and falls back to Node.
|
|
211
|
+
|
|
212
|
+
**If you do not have oam, nothing changes.** The fallback is not a re-exec: npm already started Node to run the launcher, so falling back is a plain `import()` of the server into that same process. It costs a few `existsSync` calls and no subprocess, and behaves identically to running `dist/index.js` under Node directly.
|
|
213
|
+
|
|
214
|
+
**If you do have oam,** the server runs under it. Verified equivalent on both runtimes: all 21 tools register, queries return identical rows and `dataTypeName` values, and the error paths match. oam supplies every `node:` builtin the driver needs, including `net`, `tls`, `crypto`, and `dns` (SCRAM auth and the extended query protocol both work).
|
|
215
|
+
|
|
216
|
+
**Startup cost, measured.** windows-arm64, 1.4 MB bundle, `postgres-mcp version` (full module init), every binary warmed first, mean of 12 runs:
|
|
217
|
+
|
|
218
|
+
| path | startup |
|
|
219
|
+
|---|---|
|
|
220
|
+
| standalone binary (`oam compile`) | 298ms |
|
|
221
|
+
| `oam run dist/index.js` | 306ms |
|
|
222
|
+
| `node dist/index.js` | 358ms |
|
|
223
|
+
| launcher -> Node (in-process) | 370ms |
|
|
224
|
+
| launcher -> oam (spawn) | 409ms |
|
|
225
|
+
|
|
226
|
+
oam starts **faster** than Node here. What the launcher costs is the *spawn*: reaching oam means Node has already booted, and that hop (~100ms) is larger than oam's ~52ms advantage. So through the npm `bin`, the two land within ~40ms of each other, and `POSTGRES_MCP_RUNTIME=node` is a marginal win rather than a meaningful one.
|
|
227
|
+
|
|
228
|
+
Either way it is a **one-time cost per MCP session**, not per tool call -- hosts spawn the server once and hold it open. If startup genuinely matters, the standalone binary avoids the launcher entirely and is the fastest option.
|
|
229
|
+
|
|
230
|
+
> Earlier releases of this README reported ~650-900ms for Node and ~980-1290ms for oam, and advised opting out of oam on that basis. Those figures were measured against cold, freshly-built binaries and reflected the Windows on-access virus scanner rather than either runtime. They were wrong in both magnitude and direction. Corrected in 0.9.1.
|
|
231
|
+
|
|
232
|
+
```jsonc
|
|
233
|
+
{
|
|
234
|
+
"mcpServers": {
|
|
235
|
+
"postgres": {
|
|
236
|
+
"command": "npx",
|
|
237
|
+
"args": ["-y", "@yawlabs/postgres-mcp"],
|
|
238
|
+
"env": {
|
|
239
|
+
"DATABASE_URL": "postgres://...",
|
|
240
|
+
"POSTGRES_MCP_RUNTIME": "node" // opt out of oam
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
```
|
|
205
246
|
|
|
206
247
|
### Connecting to managed Postgres (Supabase, Neon, RDS, etc.)
|
|
207
248
|
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Runtime launcher for @yawlabs/postgres-mcp.
|
|
4
|
+
*
|
|
5
|
+
* Prefers the oam runtime (https://oamjs.org) and falls back to the Node
|
|
6
|
+
* process already running this file. The server itself (`dist/index.js`) is
|
|
7
|
+
* runtime-agnostic -- it is a pre-bundled ESM file using only `node:` builtins
|
|
8
|
+
* that oam implements -- so neither path changes behavior.
|
|
9
|
+
*
|
|
10
|
+
* WHY THE FALLBACK COSTS NOTHING
|
|
11
|
+
* The fallback does NOT re-exec node. npm already started a node process to
|
|
12
|
+
* run this launcher, so falling back is a plain `import()` of the server into
|
|
13
|
+
* THIS process: zero extra spawn, zero extra startup, byte-identical behavior
|
|
14
|
+
* to invoking `dist/index.js` directly. Users without oam pay only the cost of
|
|
15
|
+
* resolving a few paths (a handful of `existsSync` calls, no subprocess).
|
|
16
|
+
*
|
|
17
|
+
* WHAT THE OAM PATH COSTS
|
|
18
|
+
* The spawn, not the runtime. windows-arm64, 1.4 MB bundle, warmed binaries,
|
|
19
|
+
* mean of 12 runs: oam run 306ms, node 358ms -- oam is the FASTER of the two.
|
|
20
|
+
* But reaching oam from here means node has already booted, and that hop
|
|
21
|
+
* (~100ms) outweighs oam's ~52ms advantage: launcher -> node 370ms,
|
|
22
|
+
* launcher -> oam 409ms. So the two land within ~40ms through the npm bin.
|
|
23
|
+
* A one-time cost per MCP session either way, not per tool call.
|
|
24
|
+
*
|
|
25
|
+
* The `oam compile` standalone binary sidesteps this entirely (298ms, no
|
|
26
|
+
* launcher, no spawn) and is the right answer if startup actually matters.
|
|
27
|
+
*
|
|
28
|
+
* DO NOT re-measure this by timing a freshly built binary. On Windows a
|
|
29
|
+
* binary that is not in the on-access scanner's cache gets rescanned on every
|
|
30
|
+
* exec, while `node` from PATH was cached long ago -- the comparison then
|
|
31
|
+
* measures the scanner and dumps the whole penalty on the new binary. That
|
|
32
|
+
* mistake produced the numbers published in 0.9.0 (node ~650-900ms, oam
|
|
33
|
+
* ~980-1290ms), which were wrong in both magnitude and direction. Warm every
|
|
34
|
+
* candidate first, or stage it out of the build directory.
|
|
35
|
+
*
|
|
36
|
+
* SELECTION
|
|
37
|
+
* POSTGRES_MCP_RUNTIME=oam require oam; fail loudly if it is missing
|
|
38
|
+
* POSTGRES_MCP_RUNTIME=node never use oam
|
|
39
|
+
* POSTGRES_MCP_RUNTIME=auto prefer oam, silently fall back (default)
|
|
40
|
+
* OAM_BIN=/path/to/oam explicit binary, checked before any discovery
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
import { spawn } from "node:child_process";
|
|
44
|
+
import { existsSync } from "node:fs";
|
|
45
|
+
import { constants, homedir } from "node:os";
|
|
46
|
+
import { delimiter, join } from "node:path";
|
|
47
|
+
import { fileURLToPath } from "node:url";
|
|
48
|
+
|
|
49
|
+
// Two forms, deliberately. `import()` on Windows REJECTS a bare `C:\...` path
|
|
50
|
+
// with ERR_UNSUPPORTED_ESM_URL_SCHEME (it reads `c:` as a protocol), so the
|
|
51
|
+
// in-process fallback must use the file:// URL. spawn(), conversely, needs a
|
|
52
|
+
// real filesystem path. Keeping both avoids converting at each call site and
|
|
53
|
+
// getting it backwards on one of them.
|
|
54
|
+
const SERVER_URL = new URL("../dist/index.js", import.meta.url);
|
|
55
|
+
const SERVER_ENTRY = fileURLToPath(SERVER_URL);
|
|
56
|
+
const isWin = process.platform === "win32";
|
|
57
|
+
const exe = isWin ? "oam.exe" : "oam";
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Locate an oam binary, or null. Ordered cheapest-and-most-explicit first;
|
|
61
|
+
* every branch is a stat, never a subprocess, so the miss case (the common one
|
|
62
|
+
* for users who have never heard of oam) stays sub-millisecond.
|
|
63
|
+
*/
|
|
64
|
+
function findOam() {
|
|
65
|
+
// 1. Explicit override wins and is never second-guessed.
|
|
66
|
+
const override = process.env.OAM_BIN;
|
|
67
|
+
if (override) return existsSync(override) ? override : null;
|
|
68
|
+
|
|
69
|
+
// 2. PATH. Resolved manually rather than by spawning `which`/`where`, which
|
|
70
|
+
// would cost a subprocess on every launch just to decide whether to spawn.
|
|
71
|
+
const pathExt = isWin ? (process.env.PATHEXT ?? ".EXE").split(";").filter(Boolean) : [""];
|
|
72
|
+
for (const dir of (process.env.PATH ?? "").split(delimiter)) {
|
|
73
|
+
if (!dir) continue;
|
|
74
|
+
for (const ext of isWin ? pathExt : [""]) {
|
|
75
|
+
const candidate = join(dir, isWin ? `oam${ext.toLowerCase()}` : "oam");
|
|
76
|
+
if (existsSync(candidate)) return candidate;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 3. The per-user locations oamjs.org's installers write to. Checked because
|
|
81
|
+
// an MCP host launched from a GUI often has a PATH that does not include
|
|
82
|
+
// them, so PATH-only discovery would miss an oam the user really has.
|
|
83
|
+
const installed = isWin
|
|
84
|
+
? [join(process.env.LOCALAPPDATA ?? join(homedir(), "AppData", "Local"), "oam", "bin", exe)]
|
|
85
|
+
: [join(homedir(), ".oam", "bin", exe)];
|
|
86
|
+
for (const candidate of installed) {
|
|
87
|
+
if (existsSync(candidate)) return candidate;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Run the server in THIS process. The zero-overhead fallback. */
|
|
94
|
+
async function runInProcess() {
|
|
95
|
+
await import(SERVER_URL.href);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const mode = (process.env.POSTGRES_MCP_RUNTIME ?? "auto").toLowerCase();
|
|
99
|
+
|
|
100
|
+
if (mode === "node") {
|
|
101
|
+
await runInProcess();
|
|
102
|
+
} else {
|
|
103
|
+
const oam = findOam();
|
|
104
|
+
|
|
105
|
+
if (!oam) {
|
|
106
|
+
if (mode === "oam") {
|
|
107
|
+
// Explicitly demanded, so this is a real misconfiguration -- do not
|
|
108
|
+
// silently do something else. writeSync because stderr is async for
|
|
109
|
+
// TTYs/pipes on Windows and process.exit truncates pending writes.
|
|
110
|
+
const { writeSync } = await import("node:fs");
|
|
111
|
+
writeSync(
|
|
112
|
+
2,
|
|
113
|
+
"postgres-mcp: POSTGRES_MCP_RUNTIME=oam but no oam binary was found.\n" +
|
|
114
|
+
"Install from https://oamjs.org, set OAM_BIN=/path/to/oam, or use POSTGRES_MCP_RUNTIME=node.\n",
|
|
115
|
+
);
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
await runInProcess();
|
|
119
|
+
} else {
|
|
120
|
+
// `--` separates oam's own flags from the script's argv. Everything after
|
|
121
|
+
// it lands in process.argv for the server, so `postgres-mcp version` and
|
|
122
|
+
// any host-supplied flags survive the hop unchanged.
|
|
123
|
+
const child = spawn(oam, ["run", SERVER_ENTRY, "--", ...process.argv.slice(2)], {
|
|
124
|
+
// inherit keeps the SAME fds, so MCP's newline-delimited JSON framing on
|
|
125
|
+
// stdin/stdout is untouched and the host's stdin-close still reaches the
|
|
126
|
+
// server's shutdown path.
|
|
127
|
+
stdio: "inherit",
|
|
128
|
+
env: process.env,
|
|
129
|
+
windowsHide: true,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// If oam cannot be executed at all (deleted between the stat and the
|
|
133
|
+
// spawn, wrong arch, permission), fall back rather than failing the whole
|
|
134
|
+
// server. `spawned` guards against falling back AFTER the child has begun
|
|
135
|
+
// running, which would double-start the server.
|
|
136
|
+
let spawned = false;
|
|
137
|
+
child.on("spawn", () => {
|
|
138
|
+
spawned = true;
|
|
139
|
+
});
|
|
140
|
+
child.on("error", (err) => {
|
|
141
|
+
if (spawned) return;
|
|
142
|
+
if (mode === "oam") {
|
|
143
|
+
process.stderr.write(`postgres-mcp: failed to launch oam (${err.message})\n`);
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
void runInProcess();
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Forward termination so the server's own SIGINT/SIGTERM cleanup (pool
|
|
150
|
+
// drain) runs in the child instead of the child being orphaned. Signals
|
|
151
|
+
// are a no-op on Windows but harmless to register.
|
|
152
|
+
for (const sig of ["SIGINT", "SIGTERM"]) {
|
|
153
|
+
process.on(sig, () => {
|
|
154
|
+
if (!child.killed) child.kill(sig);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
child.on("exit", (code, signal) => {
|
|
159
|
+
// Mirror the child's fate: a signal death becomes 128+n so callers see a
|
|
160
|
+
// conventional shell exit status rather than a bare 0.
|
|
161
|
+
if (signal) {
|
|
162
|
+
process.exit(128 + (constants.signals[signal] ?? 15));
|
|
163
|
+
}
|
|
164
|
+
process.exit(code ?? 0);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -37796,7 +37796,7 @@ function compareVersions(a, b) {
|
|
|
37796
37796
|
}
|
|
37797
37797
|
|
|
37798
37798
|
// src/index.ts
|
|
37799
|
-
var version2 = true ? "0.
|
|
37799
|
+
var version2 = true ? "0.9.1" : await readPackageVersion();
|
|
37800
37800
|
var subcommand = process.argv[2];
|
|
37801
37801
|
if (subcommand === "version" || subcommand === "--version") {
|
|
37802
37802
|
console.log(version2);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yawlabs/postgres-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"mcpName": "io.github.YawLabs/postgres-mcp",
|
|
5
5
|
"description": "PostgreSQL MCP server - query, schema introspection, explain, and health checks for AI assistants",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,9 +28,10 @@
|
|
|
28
28
|
"type": "module",
|
|
29
29
|
"main": "dist/index.js",
|
|
30
30
|
"bin": {
|
|
31
|
-
"postgres-mcp": "
|
|
31
|
+
"postgres-mcp": "bin/postgres-mcp.mjs"
|
|
32
32
|
},
|
|
33
33
|
"files": [
|
|
34
|
+
"bin/postgres-mcp.mjs",
|
|
34
35
|
"dist/index.js",
|
|
35
36
|
"LICENSE",
|
|
36
37
|
"README.md",
|