pg-admin-mcp 0.0.0-stage → 0.1.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 (130) hide show
  1. package/README.md +608 -2
  2. package/dist/config/env.js +67 -0
  3. package/dist/config/env.js.map +1 -0
  4. package/dist/config/profiles.js +257 -0
  5. package/dist/config/profiles.js.map +1 -0
  6. package/dist/core/audit-context.js +21 -0
  7. package/dist/core/audit-context.js.map +1 -0
  8. package/dist/core/audit.js +91 -0
  9. package/dist/core/audit.js.map +1 -0
  10. package/dist/core/brands.js +24 -0
  11. package/dist/core/brands.js.map +1 -0
  12. package/dist/core/classifier.js +279 -0
  13. package/dist/core/classifier.js.map +1 -0
  14. package/dist/core/errors.js +197 -0
  15. package/dist/core/errors.js.map +1 -0
  16. package/dist/core/format.js +258 -0
  17. package/dist/core/format.js.map +1 -0
  18. package/dist/core/guards.js +513 -0
  19. package/dist/core/guards.js.map +1 -0
  20. package/dist/core/identifiers.js +431 -0
  21. package/dist/core/identifiers.js.map +1 -0
  22. package/dist/core/limits.js +79 -0
  23. package/dist/core/limits.js.map +1 -0
  24. package/dist/core/logger.js +34 -0
  25. package/dist/core/logger.js.map +1 -0
  26. package/dist/core/paginate.js +195 -0
  27. package/dist/core/paginate.js.map +1 -0
  28. package/dist/core/paths.js +392 -0
  29. package/dist/core/paths.js.map +1 -0
  30. package/dist/core/policy.js +98 -0
  31. package/dist/core/policy.js.map +1 -0
  32. package/dist/core/shutdown.js +10 -0
  33. package/dist/core/shutdown.js.map +1 -0
  34. package/dist/core/stdout-guard.js +25 -0
  35. package/dist/core/stdout-guard.js.map +1 -0
  36. package/dist/db/catalog.js +1006 -0
  37. package/dist/db/catalog.js.map +1 -0
  38. package/dist/db/pool.js +158 -0
  39. package/dist/db/pool.js.map +1 -0
  40. package/dist/db/session.js +258 -0
  41. package/dist/db/session.js.map +1 -0
  42. package/dist/db/types.js +2 -0
  43. package/dist/db/types.js.map +1 -0
  44. package/dist/index.js +91 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/resources/index.js +88 -0
  47. package/dist/resources/index.js.map +1 -0
  48. package/dist/runtime/binaries.js +356 -0
  49. package/dist/runtime/binaries.js.map +1 -0
  50. package/dist/runtime/env-file.js +62 -0
  51. package/dist/runtime/env-file.js.map +1 -0
  52. package/dist/runtime/environment.js +34 -0
  53. package/dist/runtime/environment.js.map +1 -0
  54. package/dist/server.js +106 -0
  55. package/dist/server.js.map +1 -0
  56. package/dist/snapshot/capture.js +189 -0
  57. package/dist/snapshot/capture.js.map +1 -0
  58. package/dist/snapshot/diff.js +254 -0
  59. package/dist/snapshot/diff.js.map +1 -0
  60. package/dist/snapshot/migrate.js +1596 -0
  61. package/dist/snapshot/migrate.js.map +1 -0
  62. package/dist/snapshot/model.js +80 -0
  63. package/dist/snapshot/model.js.map +1 -0
  64. package/dist/tools/_archive_meta.js +138 -0
  65. package/dist/tools/_archive_meta.js.map +1 -0
  66. package/dist/tools/_batch_shared.js +73 -0
  67. package/dist/tools/_batch_shared.js.map +1 -0
  68. package/dist/tools/_export_format.js +107 -0
  69. package/dist/tools/_export_format.js.map +1 -0
  70. package/dist/tools/_object_kinds.js +97 -0
  71. package/dist/tools/_object_kinds.js.map +1 -0
  72. package/dist/tools/_relation_detail.js +55 -0
  73. package/dist/tools/_relation_detail.js.map +1 -0
  74. package/dist/tools/_shared.js +17 -0
  75. package/dist/tools/_shared.js.map +1 -0
  76. package/dist/tools/_snapshot_io.js +238 -0
  77. package/dist/tools/_snapshot_io.js.map +1 -0
  78. package/dist/tools/admin/_shared.js +18 -0
  79. package/dist/tools/admin/_shared.js.map +1 -0
  80. package/dist/tools/admin/extensions.js +80 -0
  81. package/dist/tools/admin/extensions.js.map +1 -0
  82. package/dist/tools/admin/grants.js +207 -0
  83. package/dist/tools/admin/grants.js.map +1 -0
  84. package/dist/tools/admin/index.js +138 -0
  85. package/dist/tools/admin/index.js.map +1 -0
  86. package/dist/tools/admin/maintenance.js +106 -0
  87. package/dist/tools/admin/maintenance.js.map +1 -0
  88. package/dist/tools/admin/roles.js +144 -0
  89. package/dist/tools/admin/roles.js.map +1 -0
  90. package/dist/tools/admin/sessions.js +104 -0
  91. package/dist/tools/admin/sessions.js.map +1 -0
  92. package/dist/tools/admin/stats.js +63 -0
  93. package/dist/tools/admin/stats.js.map +1 -0
  94. package/dist/tools/backup.js +288 -0
  95. package/dist/tools/backup.js.map +1 -0
  96. package/dist/tools/connection_status.js +138 -0
  97. package/dist/tools/connection_status.js.map +1 -0
  98. package/dist/tools/copy.js +355 -0
  99. package/dist/tools/copy.js.map +1 -0
  100. package/dist/tools/delete_batch.js +73 -0
  101. package/dist/tools/delete_batch.js.map +1 -0
  102. package/dist/tools/describe_object.js +87 -0
  103. package/dist/tools/describe_object.js.map +1 -0
  104. package/dist/tools/execute_sql.js +395 -0
  105. package/dist/tools/execute_sql.js.map +1 -0
  106. package/dist/tools/explain.js +134 -0
  107. package/dist/tools/explain.js.map +1 -0
  108. package/dist/tools/export.js +215 -0
  109. package/dist/tools/export.js.map +1 -0
  110. package/dist/tools/get_schema.js +148 -0
  111. package/dist/tools/get_schema.js.map +1 -0
  112. package/dist/tools/index.js +40 -0
  113. package/dist/tools/index.js.map +1 -0
  114. package/dist/tools/insert_batch.js +212 -0
  115. package/dist/tools/insert_batch.js.map +1 -0
  116. package/dist/tools/list_objects.js +160 -0
  117. package/dist/tools/list_objects.js.map +1 -0
  118. package/dist/tools/prepare_migration.js +112 -0
  119. package/dist/tools/prepare_migration.js.map +1 -0
  120. package/dist/tools/restore.js +301 -0
  121. package/dist/tools/restore.js.map +1 -0
  122. package/dist/tools/schema_diff.js +79 -0
  123. package/dist/tools/schema_diff.js.map +1 -0
  124. package/dist/tools/schema_snapshot.js +57 -0
  125. package/dist/tools/schema_snapshot.js.map +1 -0
  126. package/dist/tools/select.js +162 -0
  127. package/dist/tools/select.js.map +1 -0
  128. package/dist/tools/update_batch.js +154 -0
  129. package/dist/tools/update_batch.js.map +1 -0
  130. package/package.json +47 -5
@@ -0,0 +1,98 @@
1
+ import { CAPABILITY_ENV_SUFFIX, } from '../config/profiles.js';
2
+ import { PgMcpError, envPrefix } from './errors.js';
3
+ import { logger } from './logger.js';
4
+ /** The shape `docs/design.md` names for `core/policy.ts` — capabilities plus the environment class, in one object. */
5
+ export function resolveCapabilities(profile) {
6
+ return { ...profile.capabilities, envClass: profile.envClass };
7
+ }
8
+ /**
9
+ * `backup`/`restore` share `POLICY_ADMIN_DENIED`: the taxonomy in
10
+ * `core/errors.ts` has no dedicated code for them, and inventing one here would
11
+ * put a code in flight that no other module knows. The hint still names the
12
+ * exact variable, which is the part a caller acts on.
13
+ */
14
+ const POLICY_DENIED_CODE = {
15
+ write: 'POLICY_READ_ONLY',
16
+ ddl: 'POLICY_DDL_DENIED',
17
+ admin: 'POLICY_ADMIN_DENIED',
18
+ explainAnalyze: 'POLICY_ANALYZE_DENIED',
19
+ backup: 'POLICY_ADMIN_DENIED',
20
+ restore: 'POLICY_ADMIN_DENIED',
21
+ };
22
+ const CAPABILITY_LABEL = {
23
+ write: 'writes (INSERT / UPDATE / DELETE)',
24
+ ddl: 'DDL (CREATE / ALTER / DROP)',
25
+ admin: 'administrative operations',
26
+ explainAnalyze: 'EXPLAIN ANALYZE, which executes the statement',
27
+ backup: 'pg_dump backups',
28
+ restore: 'pg_restore restores',
29
+ };
30
+ /** The exact env var that grants `capability` on `profile`. Exported for tests and for tool descriptions. */
31
+ export function capabilityEnvVar(capability, alias) {
32
+ return `${envPrefix(alias)}_${CAPABILITY_ENV_SUFFIX[capability]}`;
33
+ }
34
+ /** Throws `POLICY_*` naming the exact env var when `profile` lacks `capability`. */
35
+ export function requireCapability(capability, profile) {
36
+ if (profile.capabilities[capability])
37
+ return;
38
+ const envVar = capabilityEnvVar(capability, profile.alias);
39
+ throw new PgMcpError({
40
+ code: POLICY_DENIED_CODE[capability],
41
+ message: `profile "${profile.alias}" (envClass ${profile.envClass}) does not permit ${CAPABILITY_LABEL[capability]}`,
42
+ hint: `set ${envVar}=true for this profile and restart the server, then re-run`,
43
+ details: { profile: profile.alias, capability, envVar, envClass: profile.envClass },
44
+ });
45
+ }
46
+ /**
47
+ * The escalation matrix.
48
+ *
49
+ * **`production`** — `expect` mandatory including `keyChecksum`, `allowRowDrift`
50
+ * forced to 0. design.md is explicit about this row.
51
+ *
52
+ * **`development`** — a bare `confirm: true` commits. A dev database is the one
53
+ * place where the cost of a mistake is a re-seed, and making the guard
54
+ * expensive there is how it gets routed around in production.
55
+ *
56
+ * **`staging`** — `expect` mandatory, `keyChecksum` optional, `allowRowDrift`
57
+ * uncapped. The reasoning, since design.md leaves this row to us:
58
+ *
59
+ * - Requiring `expect` costs nothing an agent is not already doing in
60
+ * production and buys the thing staging exists for — the *procedure* is
61
+ * rehearsed identically. If the two-call flow is first exercised against
62
+ * production, staging tested the wrong thing.
63
+ * - Requiring `keyChecksum` is where staging must diverge. Staging data is
64
+ * rewritten by fixture loads, nightly refreshes and other agents' tests, so a
65
+ * mandatory identity check fails routinely for reasons that have nothing to
66
+ * do with the change under test — and a guard that cries wolf is a guard
67
+ * someone disables. It stays available and is honoured whenever supplied;
68
+ * it is simply not a precondition.
69
+ * - Same reasoning for the drift ceiling: on a churning database, forcing
70
+ * `allowRowDrift = 0` would make every legitimate call a coin flip.
71
+ *
72
+ * Net: staging proves the *workflow*, production proves the *rows*.
73
+ */
74
+ const CONFIRM_POLICY = {
75
+ development: { requireExpect: false, requireKeyChecksum: false, maxRowDrift: undefined },
76
+ staging: { requireExpect: true, requireKeyChecksum: false, maxRowDrift: undefined },
77
+ production: { requireExpect: true, requireKeyChecksum: true, maxRowDrift: 0 },
78
+ };
79
+ export function confirmPolicyFor(envClass) {
80
+ return { envClass, ...CONFIRM_POLICY[envClass] };
81
+ }
82
+ /**
83
+ * The drift tolerance that actually applies: the caller's request, floored at 0
84
+ * and clamped to the policy ceiling.
85
+ *
86
+ * A clamp is logged rather than silently applied — a caller who asked for
87
+ * `allowRowDrift: 5` on a production profile got 0, and finding that out from a
88
+ * `GUARD_ROW_DRIFT` alone would look like a bug in the guard.
89
+ */
90
+ export function effectiveRowDrift(policy, requested, alias) {
91
+ const asked = requested === undefined || !Number.isFinite(requested) ? 0 : Math.max(0, Math.trunc(requested));
92
+ if (policy.maxRowDrift === undefined || asked <= policy.maxRowDrift)
93
+ return asked;
94
+ logger.warn(`profile "${alias}" is envClass ${policy.envClass}: allowRowDrift ${asked} clamped to ${policy.maxRowDrift} — ` +
95
+ 'the row count must match the dry run exactly');
96
+ return policy.maxRowDrift;
97
+ }
98
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/core/policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ const hooks = [];
2
+ export function onShutdown(hook) {
3
+ hooks.push(hook);
4
+ }
5
+ /** Runs every hook; one failing hook must not block the others. */
6
+ export async function runShutdownHooks() {
7
+ const pending = hooks.splice(0, hooks.length);
8
+ await Promise.allSettled(pending.map(async (hook) => hook()));
9
+ }
10
+ //# sourceMappingURL=shutdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../src/core/shutdown.ts"],"names":[],"mappings":"AAQA,MAAM,KAAK,GAAmB,EAAE,CAAC;AAEjC,MAAM,UAAU,UAAU,CAAC,IAAkB;IAC3C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACnB,CAAC;AAED,mEAAmE;AACnE,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * stdout belongs to the JSON-RPC frame stream. Nothing else may write there.
3
+ *
4
+ * This module exists — instead of three statements at the top of `index.ts` —
5
+ * because ESM hoists imports: every static import of `index.ts` is evaluated
6
+ * *before* the first statement in its body runs. A dependency that logs at
7
+ * module-evaluation time would therefore beat an inline guard. Importing this
8
+ * file first makes the guard the first code the process executes.
9
+ *
10
+ * It redirects every console method that defaults to stdout: `log`/`info`/
11
+ * `debug` write via `kWriteToConsole(kUseStdout, …)` indirectly through
12
+ * `this.log`, and so do `table`/`group`/`count`/`timeEnd` — but `dir` and
13
+ * `dirxml` call `kWriteToConsole(kUseStdout, …)` directly, bypassing `log`,
14
+ * so they need their own redirect. A dependency that calls
15
+ * `process.stdout.write` directly still bypasses all of this; that is
16
+ * deliberate — patching `process.stdout.write` would also break the
17
+ * transport itself.
18
+ */
19
+ console.log = console.error.bind(console);
20
+ console.info = console.error.bind(console);
21
+ console.debug = console.error.bind(console);
22
+ console.dir = console.error.bind(console);
23
+ console.dirxml = console.error.bind(console);
24
+ export {};
25
+ //# sourceMappingURL=stdout-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdout-guard.js","sourceRoot":"","sources":["../../src/core/stdout-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC1C,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC3C,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC5C,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC1C,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAE7C,OAAO,EAAE,CAAC"}