@yawlabs/postgres-mcp 0.6.12 → 0.6.13

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 CHANGED
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.6.13] - 2026-05-16
11
+
12
+ ### Fixed
13
+ - `pg_kill` now captures postgres's NOTICE channel during
14
+ `pg_cancel_backend` / `pg_terminate_backend` and surfaces the message in
15
+ the `note` field when `signaled=false`. Postgres distinguishes "PID N
16
+ is not a PostgreSQL backend process" from "must be a member of the role
17
+ whose query is being canceled or member of pg_signal_backend" via
18
+ NOTICE, but the boolean return collapses both to `false`. Pre-0.6.13
19
+ the handler returned a generic three-way list and the agent had to
20
+ guess; now the cause is in the response. Closes #6.
21
+
22
+ ### Docs
23
+ - `pg_kill` description now documents the NOTICE-derived `note` field.
24
+
25
+ ### Internal
26
+ - `formatPgError` is now exported from `api.ts` so handlers that bypass
27
+ `runInternal` / `withSharedClient` (currently only `pg_kill`) can format
28
+ errors consistently with the rest of the codebase.
29
+
10
30
  ## [0.6.12] - 2026-05-16
11
31
 
12
32
  ### Fixed
package/dist/index.js CHANGED
@@ -36508,7 +36508,7 @@ var adminTools = [
36508
36508
  },
36509
36509
  {
36510
36510
  name: "pg_kill",
36511
- description: "Cancel a running query (SIGINT-equivalent) or terminate a backend connection (SIGTERM-equivalent) by PID. Find the PID via `pg_health` active_queries or `pg_inspect_locks`. Requires ALLOW_WRITES=1 since this changes database session state. The role in DATABASE_URL must have permission - cancelling another user's query needs the `pg_signal_backend` role or superuser. Note: `pg_signal_backend` does NOT cover superuser-owned backends - only a superuser can signal another superuser's session. Cancel is graceful; terminate is forceful.",
36511
+ description: "Cancel a running query (SIGINT-equivalent) or terminate a backend connection (SIGTERM-equivalent) by PID. Find the PID via `pg_health` active_queries or `pg_inspect_locks`. Requires ALLOW_WRITES=1 since this changes database session state. The role in DATABASE_URL must have permission - cancelling another user's query needs the `pg_signal_backend` role or superuser. Note: `pg_signal_backend` does NOT cover superuser-owned backends - only a superuser can signal another superuser's session. Cancel is graceful; terminate is forceful. When `signaled=false`, the `note` field surfaces postgres's NOTICE explaining why (e.g. 'not a PostgreSQL backend process' for a non-pg PID, 'must be a member of...' for permission denial) so an agent can act on the specific cause rather than guess from a three-way list.",
36512
36512
  annotations: {
36513
36513
  title: "Cancel or terminate a backend",
36514
36514
  readOnlyHint: false,
@@ -36529,18 +36529,31 @@ var adminTools = [
36529
36529
  };
36530
36530
  }
36531
36531
  const fn = mode === "terminate" ? "pg_terminate_backend" : "pg_cancel_backend";
36532
- const result = await runInternal(`SELECT ${fn}($1) AS signaled`, [pid]);
36533
- if (!result.ok) return result;
36534
- const signaled = result.data?.[0]?.signaled === true;
36535
- return {
36536
- ok: true,
36537
- data: {
36538
- pid,
36539
- mode,
36540
- signaled,
36541
- note: signaled ? `Sent ${mode === "terminate" ? "SIGTERM" : "SIGINT"} to backend ${pid}.` : `Signal returned false - PID ${pid} may not exist, may already be gone, or the current role lacks permission.`
36542
- }
36532
+ const client = await getPool().connect();
36533
+ const notices = [];
36534
+ const onNotice = (n) => {
36535
+ if (n.message) notices.push(n.message);
36543
36536
  };
36537
+ client.on("notice", onNotice);
36538
+ try {
36539
+ const result = await client.query(`SELECT ${fn}($1) AS signaled`, [pid]);
36540
+ const signaled = result.rows[0]?.signaled === true;
36541
+ const noticeText = notices.join(" ").trim();
36542
+ return {
36543
+ ok: true,
36544
+ data: {
36545
+ pid,
36546
+ mode,
36547
+ signaled,
36548
+ note: signaled ? `Sent ${mode === "terminate" ? "SIGTERM" : "SIGINT"} to backend ${pid}.` : noticeText ? `${noticeText} (Signal returned false for PID ${pid}.)` : `Signal returned false - PID ${pid} may not exist, may already be gone, or the current role lacks permission.`
36549
+ }
36550
+ };
36551
+ } catch (err) {
36552
+ return { ok: false, error: formatPgError(err) };
36553
+ } finally {
36554
+ client.off("notice", onNotice);
36555
+ client.release();
36556
+ }
36544
36557
  }
36545
36558
  },
36546
36559
  {
@@ -37578,7 +37591,7 @@ function compareVersions(a, b) {
37578
37591
  }
37579
37592
 
37580
37593
  // src/index.ts
37581
- var version2 = true ? "0.6.12" : (await null).createRequire(import.meta.url)("../package.json").version;
37594
+ var version2 = true ? "0.6.13" : (await null).createRequire(import.meta.url)("../package.json").version;
37582
37595
  var subcommand = process.argv[2];
37583
37596
  if (subcommand === "version" || subcommand === "--version") {
37584
37597
  console.log(version2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yawlabs/postgres-mcp",
3
- "version": "0.6.12",
3
+ "version": "0.6.13",
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",