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.
- package/README.md +608 -2
- package/dist/config/env.js +67 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/profiles.js +257 -0
- package/dist/config/profiles.js.map +1 -0
- package/dist/core/audit-context.js +21 -0
- package/dist/core/audit-context.js.map +1 -0
- package/dist/core/audit.js +91 -0
- package/dist/core/audit.js.map +1 -0
- package/dist/core/brands.js +24 -0
- package/dist/core/brands.js.map +1 -0
- package/dist/core/classifier.js +279 -0
- package/dist/core/classifier.js.map +1 -0
- package/dist/core/errors.js +197 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/format.js +258 -0
- package/dist/core/format.js.map +1 -0
- package/dist/core/guards.js +513 -0
- package/dist/core/guards.js.map +1 -0
- package/dist/core/identifiers.js +431 -0
- package/dist/core/identifiers.js.map +1 -0
- package/dist/core/limits.js +79 -0
- package/dist/core/limits.js.map +1 -0
- package/dist/core/logger.js +34 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/paginate.js +195 -0
- package/dist/core/paginate.js.map +1 -0
- package/dist/core/paths.js +392 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/policy.js +98 -0
- package/dist/core/policy.js.map +1 -0
- package/dist/core/shutdown.js +10 -0
- package/dist/core/shutdown.js.map +1 -0
- package/dist/core/stdout-guard.js +25 -0
- package/dist/core/stdout-guard.js.map +1 -0
- package/dist/db/catalog.js +1006 -0
- package/dist/db/catalog.js.map +1 -0
- package/dist/db/pool.js +158 -0
- package/dist/db/pool.js.map +1 -0
- package/dist/db/session.js +258 -0
- package/dist/db/session.js.map +1 -0
- package/dist/db/types.js +2 -0
- package/dist/db/types.js.map +1 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/index.js +88 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/runtime/binaries.js +356 -0
- package/dist/runtime/binaries.js.map +1 -0
- package/dist/runtime/env-file.js +62 -0
- package/dist/runtime/env-file.js.map +1 -0
- package/dist/runtime/environment.js +34 -0
- package/dist/runtime/environment.js.map +1 -0
- package/dist/server.js +106 -0
- package/dist/server.js.map +1 -0
- package/dist/snapshot/capture.js +189 -0
- package/dist/snapshot/capture.js.map +1 -0
- package/dist/snapshot/diff.js +254 -0
- package/dist/snapshot/diff.js.map +1 -0
- package/dist/snapshot/migrate.js +1596 -0
- package/dist/snapshot/migrate.js.map +1 -0
- package/dist/snapshot/model.js +80 -0
- package/dist/snapshot/model.js.map +1 -0
- package/dist/tools/_archive_meta.js +138 -0
- package/dist/tools/_archive_meta.js.map +1 -0
- package/dist/tools/_batch_shared.js +73 -0
- package/dist/tools/_batch_shared.js.map +1 -0
- package/dist/tools/_export_format.js +107 -0
- package/dist/tools/_export_format.js.map +1 -0
- package/dist/tools/_object_kinds.js +97 -0
- package/dist/tools/_object_kinds.js.map +1 -0
- package/dist/tools/_relation_detail.js +55 -0
- package/dist/tools/_relation_detail.js.map +1 -0
- package/dist/tools/_shared.js +17 -0
- package/dist/tools/_shared.js.map +1 -0
- package/dist/tools/_snapshot_io.js +238 -0
- package/dist/tools/_snapshot_io.js.map +1 -0
- package/dist/tools/admin/_shared.js +18 -0
- package/dist/tools/admin/_shared.js.map +1 -0
- package/dist/tools/admin/extensions.js +80 -0
- package/dist/tools/admin/extensions.js.map +1 -0
- package/dist/tools/admin/grants.js +207 -0
- package/dist/tools/admin/grants.js.map +1 -0
- package/dist/tools/admin/index.js +138 -0
- package/dist/tools/admin/index.js.map +1 -0
- package/dist/tools/admin/maintenance.js +106 -0
- package/dist/tools/admin/maintenance.js.map +1 -0
- package/dist/tools/admin/roles.js +144 -0
- package/dist/tools/admin/roles.js.map +1 -0
- package/dist/tools/admin/sessions.js +104 -0
- package/dist/tools/admin/sessions.js.map +1 -0
- package/dist/tools/admin/stats.js +63 -0
- package/dist/tools/admin/stats.js.map +1 -0
- package/dist/tools/backup.js +288 -0
- package/dist/tools/backup.js.map +1 -0
- package/dist/tools/connection_status.js +138 -0
- package/dist/tools/connection_status.js.map +1 -0
- package/dist/tools/copy.js +355 -0
- package/dist/tools/copy.js.map +1 -0
- package/dist/tools/delete_batch.js +73 -0
- package/dist/tools/delete_batch.js.map +1 -0
- package/dist/tools/describe_object.js +87 -0
- package/dist/tools/describe_object.js.map +1 -0
- package/dist/tools/execute_sql.js +395 -0
- package/dist/tools/execute_sql.js.map +1 -0
- package/dist/tools/explain.js +134 -0
- package/dist/tools/explain.js.map +1 -0
- package/dist/tools/export.js +215 -0
- package/dist/tools/export.js.map +1 -0
- package/dist/tools/get_schema.js +148 -0
- package/dist/tools/get_schema.js.map +1 -0
- package/dist/tools/index.js +40 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/insert_batch.js +212 -0
- package/dist/tools/insert_batch.js.map +1 -0
- package/dist/tools/list_objects.js +160 -0
- package/dist/tools/list_objects.js.map +1 -0
- package/dist/tools/prepare_migration.js +112 -0
- package/dist/tools/prepare_migration.js.map +1 -0
- package/dist/tools/restore.js +301 -0
- package/dist/tools/restore.js.map +1 -0
- package/dist/tools/schema_diff.js +79 -0
- package/dist/tools/schema_diff.js.map +1 -0
- package/dist/tools/schema_snapshot.js +57 -0
- package/dist/tools/schema_snapshot.js.map +1 -0
- package/dist/tools/select.js +162 -0
- package/dist/tools/select.js.map +1 -0
- package/dist/tools/update_batch.js +154 -0
- package/dist/tools/update_batch.js.map +1 -0
- 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"}
|