postgres-aiops 0.1.0__tar.gz
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.
- postgres_aiops-0.1.0/.github/workflows/publish.yml +26 -0
- postgres_aiops-0.1.0/.gitignore +7 -0
- postgres_aiops-0.1.0/CHANGELOG.md +62 -0
- postgres_aiops-0.1.0/LICENSE +21 -0
- postgres_aiops-0.1.0/PKG-INFO +119 -0
- postgres_aiops-0.1.0/README.md +103 -0
- postgres_aiops-0.1.0/RELEASE_NOTES.md +52 -0
- postgres_aiops-0.1.0/SECURITY.md +89 -0
- postgres_aiops-0.1.0/mcp_server/__init__.py +1 -0
- postgres_aiops-0.1.0/mcp_server/_shared.py +101 -0
- postgres_aiops-0.1.0/mcp_server/server.py +37 -0
- postgres_aiops-0.1.0/mcp_server/tools/__init__.py +1 -0
- postgres_aiops-0.1.0/mcp_server/tools/activity.py +52 -0
- postgres_aiops-0.1.0/mcp_server/tools/analysis.py +89 -0
- postgres_aiops-0.1.0/mcp_server/tools/indexes.py +65 -0
- postgres_aiops-0.1.0/mcp_server/tools/queries.py +60 -0
- postgres_aiops-0.1.0/mcp_server/tools/remediation.py +281 -0
- postgres_aiops-0.1.0/mcp_server/tools/replication.py +43 -0
- postgres_aiops-0.1.0/mcp_server/tools/server.py +86 -0
- postgres_aiops-0.1.0/mcp_server/tools/tables.py +46 -0
- postgres_aiops-0.1.0/postgres_aiops/__init__.py +9 -0
- postgres_aiops-0.1.0/postgres_aiops/cli/__init__.py +9 -0
- postgres_aiops-0.1.0/postgres_aiops/cli/_common.py +78 -0
- postgres_aiops-0.1.0/postgres_aiops/cli/_root.py +68 -0
- postgres_aiops-0.1.0/postgres_aiops/cli/activity.py +52 -0
- postgres_aiops-0.1.0/postgres_aiops/cli/analyze.py +53 -0
- postgres_aiops-0.1.0/postgres_aiops/cli/doctor.py +21 -0
- postgres_aiops-0.1.0/postgres_aiops/cli/index.py +55 -0
- postgres_aiops-0.1.0/postgres_aiops/cli/init.py +112 -0
- postgres_aiops-0.1.0/postgres_aiops/cli/overview.py +16 -0
- postgres_aiops-0.1.0/postgres_aiops/cli/query.py +70 -0
- postgres_aiops-0.1.0/postgres_aiops/cli/remediate.py +186 -0
- postgres_aiops-0.1.0/postgres_aiops/cli/replication.py +45 -0
- postgres_aiops-0.1.0/postgres_aiops/cli/secret.py +103 -0
- postgres_aiops-0.1.0/postgres_aiops/cli/server.py +69 -0
- postgres_aiops-0.1.0/postgres_aiops/cli/table.py +45 -0
- postgres_aiops-0.1.0/postgres_aiops/config.py +154 -0
- postgres_aiops-0.1.0/postgres_aiops/connection.py +178 -0
- postgres_aiops-0.1.0/postgres_aiops/doctor.py +84 -0
- postgres_aiops-0.1.0/postgres_aiops/governance/__init__.py +40 -0
- postgres_aiops-0.1.0/postgres_aiops/governance/audit.py +377 -0
- postgres_aiops-0.1.0/postgres_aiops/governance/budget.py +225 -0
- postgres_aiops-0.1.0/postgres_aiops/governance/decorators.py +474 -0
- postgres_aiops-0.1.0/postgres_aiops/governance/paths.py +23 -0
- postgres_aiops-0.1.0/postgres_aiops/governance/patterns.py +378 -0
- postgres_aiops-0.1.0/postgres_aiops/governance/policy.py +411 -0
- postgres_aiops-0.1.0/postgres_aiops/governance/sanitize.py +39 -0
- postgres_aiops-0.1.0/postgres_aiops/governance/undo.py +218 -0
- postgres_aiops-0.1.0/postgres_aiops/ops/__init__.py +1 -0
- postgres_aiops-0.1.0/postgres_aiops/ops/_util.py +102 -0
- postgres_aiops-0.1.0/postgres_aiops/ops/activity.py +193 -0
- postgres_aiops-0.1.0/postgres_aiops/ops/analysis.py +263 -0
- postgres_aiops-0.1.0/postgres_aiops/ops/indexes.py +211 -0
- postgres_aiops-0.1.0/postgres_aiops/ops/overview.py +51 -0
- postgres_aiops-0.1.0/postgres_aiops/ops/queries.py +123 -0
- postgres_aiops-0.1.0/postgres_aiops/ops/remediation.py +237 -0
- postgres_aiops-0.1.0/postgres_aiops/ops/replication.py +144 -0
- postgres_aiops-0.1.0/postgres_aiops/ops/server.py +151 -0
- postgres_aiops-0.1.0/postgres_aiops/ops/tables.py +146 -0
- postgres_aiops-0.1.0/postgres_aiops/secretstore.py +302 -0
- postgres_aiops-0.1.0/pyproject.toml +59 -0
- postgres_aiops-0.1.0/server.json +21 -0
- postgres_aiops-0.1.0/skills/postgres-aiops/SKILL.md +116 -0
- postgres_aiops-0.1.0/skills/postgres-aiops/references/capabilities.md +66 -0
- postgres_aiops-0.1.0/skills/postgres-aiops/references/cli-reference.md +76 -0
- postgres_aiops-0.1.0/skills/postgres-aiops/references/setup-guide.md +97 -0
- postgres_aiops-0.1.0/smithery.yaml +9 -0
- postgres_aiops-0.1.0/tests/conftest.py +54 -0
- postgres_aiops-0.1.0/tests/test_analysis.py +84 -0
- postgres_aiops-0.1.0/tests/test_connection.py +105 -0
- postgres_aiops-0.1.0/tests/test_reads.py +179 -0
- postgres_aiops-0.1.0/tests/test_secretstore.py +99 -0
- postgres_aiops-0.1.0/tests/test_smoke.py +216 -0
- postgres_aiops-0.1.0/tests/test_writes.py +159 -0
- postgres_aiops-0.1.0/uv.lock +1040 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
# Trusted Publishing (OIDC) — publishes from GitHub's runners with no API token,
|
|
4
|
+
# sidestepping the local-IP / account new-project rate limit. Configure a matching
|
|
5
|
+
# "trusted publisher" for this package on PyPI (see the repo release notes).
|
|
6
|
+
on:
|
|
7
|
+
release:
|
|
8
|
+
types: [published]
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
publish:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
permissions:
|
|
18
|
+
id-token: write # required for PyPI Trusted Publishing (OIDC)
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- name: Set up uv
|
|
22
|
+
uses: astral-sh/setup-uv@v5
|
|
23
|
+
- name: Build sdist + wheel
|
|
24
|
+
run: uv build
|
|
25
|
+
- name: Publish to PyPI (Trusted Publishing)
|
|
26
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to postgres-aiops are documented here. Format loosely follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/); this project uses semantic
|
|
5
|
+
versioning (currently 0.x preview — the API may change).
|
|
6
|
+
|
|
7
|
+
## [0.1.0] — 2026-07-13
|
|
8
|
+
|
|
9
|
+
Initial preview release: governed AI-ops for **PostgreSQL DBA operations** —
|
|
10
|
+
connecting via **psycopg 3** and reading the system catalogs and `pg_stat_*`
|
|
11
|
+
views — with a bundled governance harness. **Mock-validated only — not run
|
|
12
|
+
against a live cluster.** Community-maintained; not affiliated with the
|
|
13
|
+
PostgreSQL project.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **psycopg 3 connection layer** (`postgres_aiops.connection`) — parameterised
|
|
18
|
+
reads with a `dict_row` factory, autocommit for maintenance statements
|
|
19
|
+
(VACUUM / CONCURRENTLY / REINDEX), an injectable connection for tests, and
|
|
20
|
+
teaching error translation (`PgError`, with connect/permission/missing-view
|
|
21
|
+
hints).
|
|
22
|
+
- **33 governed MCP tools**, every one wrapped with `@governed_tool`:
|
|
23
|
+
- **Overview** — `overview` (one-shot cluster health snapshot).
|
|
24
|
+
- **Server** — `server_version`, `show_settings`, `list_extensions`,
|
|
25
|
+
`list_databases`, `list_roles`.
|
|
26
|
+
- **Activity** — `list_activity`, `long_running_queries`, `list_locks`.
|
|
27
|
+
- **Queries** — `top_queries` (pg_stat_statements), `explain_query`.
|
|
28
|
+
- **Indexes** — `unused_indexes`, `missing_index_hints`, `index_bloat`,
|
|
29
|
+
`invalid_indexes`.
|
|
30
|
+
- **Tables** — `table_sizes`, `table_bloat`, `autovacuum_status`.
|
|
31
|
+
- **Replication** — `replication_status`, `replication_slots`, `wal_status`.
|
|
32
|
+
- **Analysis (flagship)** — `slow_query_rca`, `bloat_and_vacuum_analysis`,
|
|
33
|
+
`blocking_lock_chain_rca`.
|
|
34
|
+
- **Writes** — `terminate_backend` (high), `cancel_query` (high),
|
|
35
|
+
`drop_index` (high), `run_vacuum` (medium), `run_analyze` (medium),
|
|
36
|
+
`create_index` (medium), `reindex` (medium), `update_setting` (medium),
|
|
37
|
+
`reset_query_stats` (medium).
|
|
38
|
+
- **Guarded writes** — every write supports a `dry_run` preview and (at the CLI)
|
|
39
|
+
double confirmation. Reversible writes fetch the **real before-state** and
|
|
40
|
+
record a faithful inverse: `create_index`↔`drop_index` (drop captures
|
|
41
|
+
`pg_get_indexdef` so undo recreates it exactly); `update_setting` captures the
|
|
42
|
+
prior value. Irreversible ops record prior stats for audit but no undo.
|
|
43
|
+
- **SQL-injection defenses** — all values are bound query parameters; the few
|
|
44
|
+
identifiers that cannot be parameterised (table/index/GUC names, ORDER BY
|
|
45
|
+
columns, index methods) are validated against strict allow-lists and quoted
|
|
46
|
+
before interpolation.
|
|
47
|
+
- **Bundled governance harness** (`postgres_aiops.governance`) — audit log, policy
|
|
48
|
+
engine, token/runaway budget guard, undo-token recording, graduated risk tiers,
|
|
49
|
+
prompt-injection `sanitize`. State under `~/.postgres-aiops/` (relocatable via
|
|
50
|
+
`POSTGRES_AIOPS_HOME`).
|
|
51
|
+
- **Encrypted secret store** — role passwords in `~/.postgres-aiops/secrets.enc`
|
|
52
|
+
(Fernet + scrypt); legacy `PG_<TARGET>_PASSWORD` env fallback + `secret migrate`.
|
|
53
|
+
- **CLI** — `init` wizard, `overview`, `server`, `activity`, `query`, `index`,
|
|
54
|
+
`table`, `repl`, `analyze`, `remediate`, `secret`, `doctor`, `mcp`.
|
|
55
|
+
|
|
56
|
+
### Known limitations
|
|
57
|
+
|
|
58
|
+
- Preview / mock-only: catalog and `pg_stat_*` queries need live verification.
|
|
59
|
+
- `top_queries` / `slow_query_rca` require the `pg_stat_statements` extension.
|
|
60
|
+
- Coverage is a curated subset of PostgreSQL's surface; open an issue/PR for gaps.
|
|
61
|
+
|
|
62
|
+
[0.1.0]: https://github.com/AIops-tools/Postgres-AIops/releases/tag/v0.1.0
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 wei <zhouwei008@gmail.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: postgres-aiops
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Governed AI-ops for PostgreSQL DBA operations: slow-query RCA, bloat/vacuum & blocking-lock analysis with a built-in governance harness (audit, budget, undo, risk tiers)
|
|
5
|
+
Author-email: wei <zhouwei008@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Python: >=3.11
|
|
9
|
+
Requires-Dist: cryptography>=42.0
|
|
10
|
+
Requires-Dist: mcp[cli]<2.0,>=1.10
|
|
11
|
+
Requires-Dist: psycopg[binary]<4.0,>=3.1
|
|
12
|
+
Requires-Dist: pyyaml<7.0,>=6.0
|
|
13
|
+
Requires-Dist: rich<16.0,>=13.0
|
|
14
|
+
Requires-Dist: typer<1.0,>=0.12
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
<!-- mcp-name: io.github.AIops-tools/postgres-aiops -->
|
|
18
|
+
|
|
19
|
+
# Postgres AIops (preview)
|
|
20
|
+
|
|
21
|
+
> **Disclaimer**: Community-maintained open-source project. **Not affiliated with, endorsed by, or sponsored by the PostgreSQL Global Development Group or any vendor.** "PostgreSQL" and the elephant logo are trademarks of the PostgreSQL Community Association; all product/trademark names belong to their respective owners. MIT licensed.
|
|
22
|
+
|
|
23
|
+
Governed AI-ops for **PostgreSQL DBA operations** — connecting to a server with
|
|
24
|
+
**psycopg 3** and reading the system catalogs and `pg_stat_*` views — with a
|
|
25
|
+
**built-in governance harness**: unified audit log, policy engine, token/runaway
|
|
26
|
+
budget guard, undo-token recording, and graduated-autonomy risk tiers.
|
|
27
|
+
**Preview — mock-validated only, not run against a live cluster.**
|
|
28
|
+
|
|
29
|
+
## What it does
|
|
30
|
+
|
|
31
|
+
Three flagship signature analyses, plus the guarded reads and writes around them:
|
|
32
|
+
|
|
33
|
+
- **Slow-query RCA** — take the worst `pg_stat_statements` entry (plus an optional
|
|
34
|
+
`EXPLAIN` plan) and map its numbers — mean time, cache-hit ratio, temp spill,
|
|
35
|
+
call count, plan node types — to a cited cause and a concrete action. Every
|
|
36
|
+
finding carries its measured number, not a black-box verdict.
|
|
37
|
+
- **Bloat & vacuum analysis** — combine per-table dead-tuple ratio and autovacuum
|
|
38
|
+
recency into a ranked, cited recommendation (VACUUM / tune autovacuum).
|
|
39
|
+
- **Blocking lock-chain RCA** — build the wait-for tree from `pg_blocking_pids`,
|
|
40
|
+
name the **root blocker** (blocks others, waits on none), and give the action;
|
|
41
|
+
a cycle is flagged as a likely deadlock.
|
|
42
|
+
|
|
43
|
+
## What works
|
|
44
|
+
|
|
45
|
+
- **CLI** (`postgres-aiops ...`): `init`, `overview`, `server`, `activity`, `query`, `index`, `table`, `repl`, `analyze`, `remediate`, `secret`, `doctor`, `mcp`.
|
|
46
|
+
- **MCP server** (`postgres-aiops mcp` or `postgres-aiops-mcp`): **33 tools** (24 read, 9 write), every one wrapped with the bundled `@governed_tool` harness.
|
|
47
|
+
- **Encrypted credentials**: the role password lives in an encrypted store `~/.postgres-aiops/secrets.enc` (Fernet + scrypt) — **never plaintext on disk**. Unlock with a master password from `POSTGRES_AIOPS_MASTER_PASSWORD` (MCP/CI) or an interactive prompt (CLI).
|
|
48
|
+
- **Reversibility**: mutating writes fetch the **real before-state first** and record a faithful inverse — `create_index`↔`drop_index`; `drop_index` captures `pg_get_indexdef` so undo recreates it exactly; `update_setting` captures the prior value so undo sets it back. Irreversible ops (`terminate_backend`, `cancel_query`, `run_vacuum`, `run_analyze`, `reindex`, `reset_query_stats`) record prior stats for audit but declare no undo.
|
|
49
|
+
- **Safety**: every state-changing CLI op supports `--dry-run` and requires double confirmation; every write MCP tool takes a `dry_run` preview. All identifiers that cannot be parameterised (table/index/GUC names) are validated and quoted; all values are bound query parameters.
|
|
50
|
+
|
|
51
|
+
## Capability matrix (33 MCP tools)
|
|
52
|
+
|
|
53
|
+
| Domain | Tools | Count | R/W |
|
|
54
|
+
|--------|-------|:-----:|:---:|
|
|
55
|
+
| **Overview** | `overview` | 1 | read |
|
|
56
|
+
| **Server** | `server_version`, `show_settings`, `list_extensions`, `list_databases`, `list_roles` | 5 | read |
|
|
57
|
+
| **Activity** | `list_activity`, `long_running_queries`, `list_locks` | 3 | read |
|
|
58
|
+
| **Queries** | `top_queries`, `explain_query` | 2 | read |
|
|
59
|
+
| **Indexes** | `unused_indexes`, `missing_index_hints`, `index_bloat`, `invalid_indexes` | 4 | read |
|
|
60
|
+
| **Tables** | `table_sizes`, `table_bloat`, `autovacuum_status` | 3 | read |
|
|
61
|
+
| **Replication** | `replication_status`, `replication_slots`, `wal_status` | 3 | read |
|
|
62
|
+
| **Analysis (flagship)** | `slow_query_rca`, `bloat_and_vacuum_analysis`, `blocking_lock_chain_rca` | 3 | read |
|
|
63
|
+
| **Writes** | `terminate_backend`, `cancel_query`, `drop_index` | 3 | write (high) |
|
|
64
|
+
| | `run_vacuum`, `run_analyze`, `create_index`, `reindex`, `update_setting`, `reset_query_stats` | 6 | write (medium) |
|
|
65
|
+
|
|
66
|
+
The flagship analyses accept injected records for pure/offline analysis, or pull
|
|
67
|
+
live from a configured target. `top_queries`/`slow_query_rca` require the
|
|
68
|
+
`pg_stat_statements` extension; the read role should have `pg_monitor`.
|
|
69
|
+
|
|
70
|
+
## Quick start
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
uv tool install postgres-aiops # or: pipx install postgres-aiops
|
|
74
|
+
postgres-aiops init # wizard: add a target + store the password (encrypted)
|
|
75
|
+
postgres-aiops doctor # verify config, secrets, connectivity
|
|
76
|
+
postgres-aiops overview # one-shot cluster health snapshot
|
|
77
|
+
postgres-aiops analyze slow-query # RCA the worst pg_stat_statements entry
|
|
78
|
+
postgres-aiops table bloat # dead-tuple bloat proxy per table
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Run as an MCP server (stdio):
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
export POSTGRES_AIOPS_MASTER_PASSWORD=... # unlock secrets non-interactively
|
|
85
|
+
postgres-aiops-mcp
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Governance
|
|
89
|
+
|
|
90
|
+
Every MCP tool passes through the bundled `@governed_tool` harness:
|
|
91
|
+
|
|
92
|
+
- **Audit** — every call (params, result, status, duration, risk tier, approver,
|
|
93
|
+
rationale) is logged to `~/.postgres-aiops/audit.db` (relocatable via
|
|
94
|
+
`POSTGRES_AIOPS_HOME`).
|
|
95
|
+
- **Budget / runaway guard** — token and call budgets trip a circuit breaker.
|
|
96
|
+
- **Risk tiers** — graduated autonomy; high-risk ops can require a named approver
|
|
97
|
+
(`POSTGRES_AUDIT_APPROVED_BY` / `POSTGRES_AUDIT_RATIONALE` — the env-var names
|
|
98
|
+
the bundled harness reads).
|
|
99
|
+
- **Undo recording** — reversible writes record an inverse descriptor built from
|
|
100
|
+
the fetched before-state.
|
|
101
|
+
|
|
102
|
+
## Scope
|
|
103
|
+
|
|
104
|
+
This is the **PostgreSQL DBA-ops** member of the AIops-tools family (governed
|
|
105
|
+
AI-ops with audit + budget + undo + risk tiers). Do **NOT** use it for OT /
|
|
106
|
+
industrial edge (Modbus, OPC-UA, PROFINET) — see the separate `industrial-aiops`
|
|
107
|
+
line — nor for application-schema migrations or ORM management.
|
|
108
|
+
|
|
109
|
+
## Missing a capability?
|
|
110
|
+
|
|
111
|
+
Coverage is intentionally a curated subset of PostgreSQL's catalogs and
|
|
112
|
+
maintenance surface. Missing a view, a metric, or a maintenance command? **Open
|
|
113
|
+
an issue or PR** — contributions welcome.
|
|
114
|
+
|
|
115
|
+
## Status
|
|
116
|
+
|
|
117
|
+
**Preview — mock-validated only, not run against a live cluster.** The catalog
|
|
118
|
+
queries are modelled from the documented `pg_catalog` / `pg_stat_*` shapes and
|
|
119
|
+
need live verification. `postgres-aiops doctor` is the fastest live check.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<!-- mcp-name: io.github.AIops-tools/postgres-aiops -->
|
|
2
|
+
|
|
3
|
+
# Postgres AIops (preview)
|
|
4
|
+
|
|
5
|
+
> **Disclaimer**: Community-maintained open-source project. **Not affiliated with, endorsed by, or sponsored by the PostgreSQL Global Development Group or any vendor.** "PostgreSQL" and the elephant logo are trademarks of the PostgreSQL Community Association; all product/trademark names belong to their respective owners. MIT licensed.
|
|
6
|
+
|
|
7
|
+
Governed AI-ops for **PostgreSQL DBA operations** — connecting to a server with
|
|
8
|
+
**psycopg 3** and reading the system catalogs and `pg_stat_*` views — with a
|
|
9
|
+
**built-in governance harness**: unified audit log, policy engine, token/runaway
|
|
10
|
+
budget guard, undo-token recording, and graduated-autonomy risk tiers.
|
|
11
|
+
**Preview — mock-validated only, not run against a live cluster.**
|
|
12
|
+
|
|
13
|
+
## What it does
|
|
14
|
+
|
|
15
|
+
Three flagship signature analyses, plus the guarded reads and writes around them:
|
|
16
|
+
|
|
17
|
+
- **Slow-query RCA** — take the worst `pg_stat_statements` entry (plus an optional
|
|
18
|
+
`EXPLAIN` plan) and map its numbers — mean time, cache-hit ratio, temp spill,
|
|
19
|
+
call count, plan node types — to a cited cause and a concrete action. Every
|
|
20
|
+
finding carries its measured number, not a black-box verdict.
|
|
21
|
+
- **Bloat & vacuum analysis** — combine per-table dead-tuple ratio and autovacuum
|
|
22
|
+
recency into a ranked, cited recommendation (VACUUM / tune autovacuum).
|
|
23
|
+
- **Blocking lock-chain RCA** — build the wait-for tree from `pg_blocking_pids`,
|
|
24
|
+
name the **root blocker** (blocks others, waits on none), and give the action;
|
|
25
|
+
a cycle is flagged as a likely deadlock.
|
|
26
|
+
|
|
27
|
+
## What works
|
|
28
|
+
|
|
29
|
+
- **CLI** (`postgres-aiops ...`): `init`, `overview`, `server`, `activity`, `query`, `index`, `table`, `repl`, `analyze`, `remediate`, `secret`, `doctor`, `mcp`.
|
|
30
|
+
- **MCP server** (`postgres-aiops mcp` or `postgres-aiops-mcp`): **33 tools** (24 read, 9 write), every one wrapped with the bundled `@governed_tool` harness.
|
|
31
|
+
- **Encrypted credentials**: the role password lives in an encrypted store `~/.postgres-aiops/secrets.enc` (Fernet + scrypt) — **never plaintext on disk**. Unlock with a master password from `POSTGRES_AIOPS_MASTER_PASSWORD` (MCP/CI) or an interactive prompt (CLI).
|
|
32
|
+
- **Reversibility**: mutating writes fetch the **real before-state first** and record a faithful inverse — `create_index`↔`drop_index`; `drop_index` captures `pg_get_indexdef` so undo recreates it exactly; `update_setting` captures the prior value so undo sets it back. Irreversible ops (`terminate_backend`, `cancel_query`, `run_vacuum`, `run_analyze`, `reindex`, `reset_query_stats`) record prior stats for audit but declare no undo.
|
|
33
|
+
- **Safety**: every state-changing CLI op supports `--dry-run` and requires double confirmation; every write MCP tool takes a `dry_run` preview. All identifiers that cannot be parameterised (table/index/GUC names) are validated and quoted; all values are bound query parameters.
|
|
34
|
+
|
|
35
|
+
## Capability matrix (33 MCP tools)
|
|
36
|
+
|
|
37
|
+
| Domain | Tools | Count | R/W |
|
|
38
|
+
|--------|-------|:-----:|:---:|
|
|
39
|
+
| **Overview** | `overview` | 1 | read |
|
|
40
|
+
| **Server** | `server_version`, `show_settings`, `list_extensions`, `list_databases`, `list_roles` | 5 | read |
|
|
41
|
+
| **Activity** | `list_activity`, `long_running_queries`, `list_locks` | 3 | read |
|
|
42
|
+
| **Queries** | `top_queries`, `explain_query` | 2 | read |
|
|
43
|
+
| **Indexes** | `unused_indexes`, `missing_index_hints`, `index_bloat`, `invalid_indexes` | 4 | read |
|
|
44
|
+
| **Tables** | `table_sizes`, `table_bloat`, `autovacuum_status` | 3 | read |
|
|
45
|
+
| **Replication** | `replication_status`, `replication_slots`, `wal_status` | 3 | read |
|
|
46
|
+
| **Analysis (flagship)** | `slow_query_rca`, `bloat_and_vacuum_analysis`, `blocking_lock_chain_rca` | 3 | read |
|
|
47
|
+
| **Writes** | `terminate_backend`, `cancel_query`, `drop_index` | 3 | write (high) |
|
|
48
|
+
| | `run_vacuum`, `run_analyze`, `create_index`, `reindex`, `update_setting`, `reset_query_stats` | 6 | write (medium) |
|
|
49
|
+
|
|
50
|
+
The flagship analyses accept injected records for pure/offline analysis, or pull
|
|
51
|
+
live from a configured target. `top_queries`/`slow_query_rca` require the
|
|
52
|
+
`pg_stat_statements` extension; the read role should have `pg_monitor`.
|
|
53
|
+
|
|
54
|
+
## Quick start
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
uv tool install postgres-aiops # or: pipx install postgres-aiops
|
|
58
|
+
postgres-aiops init # wizard: add a target + store the password (encrypted)
|
|
59
|
+
postgres-aiops doctor # verify config, secrets, connectivity
|
|
60
|
+
postgres-aiops overview # one-shot cluster health snapshot
|
|
61
|
+
postgres-aiops analyze slow-query # RCA the worst pg_stat_statements entry
|
|
62
|
+
postgres-aiops table bloat # dead-tuple bloat proxy per table
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Run as an MCP server (stdio):
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
export POSTGRES_AIOPS_MASTER_PASSWORD=... # unlock secrets non-interactively
|
|
69
|
+
postgres-aiops-mcp
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Governance
|
|
73
|
+
|
|
74
|
+
Every MCP tool passes through the bundled `@governed_tool` harness:
|
|
75
|
+
|
|
76
|
+
- **Audit** — every call (params, result, status, duration, risk tier, approver,
|
|
77
|
+
rationale) is logged to `~/.postgres-aiops/audit.db` (relocatable via
|
|
78
|
+
`POSTGRES_AIOPS_HOME`).
|
|
79
|
+
- **Budget / runaway guard** — token and call budgets trip a circuit breaker.
|
|
80
|
+
- **Risk tiers** — graduated autonomy; high-risk ops can require a named approver
|
|
81
|
+
(`POSTGRES_AUDIT_APPROVED_BY` / `POSTGRES_AUDIT_RATIONALE` — the env-var names
|
|
82
|
+
the bundled harness reads).
|
|
83
|
+
- **Undo recording** — reversible writes record an inverse descriptor built from
|
|
84
|
+
the fetched before-state.
|
|
85
|
+
|
|
86
|
+
## Scope
|
|
87
|
+
|
|
88
|
+
This is the **PostgreSQL DBA-ops** member of the AIops-tools family (governed
|
|
89
|
+
AI-ops with audit + budget + undo + risk tiers). Do **NOT** use it for OT /
|
|
90
|
+
industrial edge (Modbus, OPC-UA, PROFINET) — see the separate `industrial-aiops`
|
|
91
|
+
line — nor for application-schema migrations or ORM management.
|
|
92
|
+
|
|
93
|
+
## Missing a capability?
|
|
94
|
+
|
|
95
|
+
Coverage is intentionally a curated subset of PostgreSQL's catalogs and
|
|
96
|
+
maintenance surface. Missing a view, a metric, or a maintenance command? **Open
|
|
97
|
+
an issue or PR** — contributions welcome.
|
|
98
|
+
|
|
99
|
+
## Status
|
|
100
|
+
|
|
101
|
+
**Preview — mock-validated only, not run against a live cluster.** The catalog
|
|
102
|
+
queries are modelled from the documented `pg_catalog` / `pg_stat_*` shapes and
|
|
103
|
+
need live verification. `postgres-aiops doctor` is the fastest live check.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Postgres AIops v0.1.0 — preview
|
|
2
|
+
|
|
3
|
+
Governed AI-ops for **PostgreSQL DBA operations** for AI agents — connecting via
|
|
4
|
+
**psycopg 3** and reading the system catalogs and `pg_stat_*` views — with a
|
|
5
|
+
built-in governance harness (audit, policy, token/runaway budget, undo-token
|
|
6
|
+
recording, graduated risk tiers) and an encrypted credential store. Standalone —
|
|
7
|
+
no external skill-family dependency.
|
|
8
|
+
|
|
9
|
+
> **Preview / mock-only.** All behaviour is validated against a mocked psycopg
|
|
10
|
+
> cursor/connection; it has **not** been run against a live PostgreSQL cluster.
|
|
11
|
+
> The fastest live check is `postgres-aiops doctor`.
|
|
12
|
+
>
|
|
13
|
+
> Community-maintained; **not affiliated with or endorsed by the PostgreSQL
|
|
14
|
+
> Global Development Group.** "PostgreSQL" and related trademarks belong to their
|
|
15
|
+
> owners.
|
|
16
|
+
|
|
17
|
+
## Highlights
|
|
18
|
+
|
|
19
|
+
- **33 MCP tools** (24 read, 9 write), every one wrapped with `@governed_tool`.
|
|
20
|
+
- Read: cluster `overview`; server (5); activity (3); query stats (2); index
|
|
21
|
+
health (4); table health (3); replication (3); and three flagship analyses.
|
|
22
|
+
- Write: `terminate_backend`/`cancel_query`/`drop_index` (high);
|
|
23
|
+
`run_vacuum`/`run_analyze`/`create_index`/`reindex`/`update_setting`/
|
|
24
|
+
`reset_query_stats` (medium).
|
|
25
|
+
- **Three signature analyses** — `slow_query_rca` (worst `pg_stat_statements`
|
|
26
|
+
entry + EXPLAIN → cited cause/action), `bloat_and_vacuum_analysis` (dead-tuple
|
|
27
|
+
ratio + autovacuum recency → recommendation), and `blocking_lock_chain_rca`
|
|
28
|
+
(build the wait-for tree, name the root blocker).
|
|
29
|
+
- **Encrypted password store** (`~/.postgres-aiops/secrets.enc`, Fernet + scrypt)
|
|
30
|
+
— never plaintext on disk; legacy `PG_<TARGET>_PASSWORD` env fallback.
|
|
31
|
+
- **CLI** with an `init` onboarding wizard, `secret` management, and `doctor`.
|
|
32
|
+
- **psycopg 3 connection layer** — parameterised catalog reads, `dict_row`
|
|
33
|
+
results, autocommit for maintenance commands, and teaching error translation
|
|
34
|
+
(`PgError`). Reversible writes fetch the real before-state first.
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
uv tool install postgres-aiops
|
|
40
|
+
postgres-aiops init
|
|
41
|
+
postgres-aiops doctor
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Caveats
|
|
45
|
+
|
|
46
|
+
- The catalog / `pg_stat_*` queries are modelled from the documented shapes and
|
|
47
|
+
need live verification against a real cluster.
|
|
48
|
+
- `top_queries` / `slow_query_rca` require the `pg_stat_statements` extension;
|
|
49
|
+
the read role should have `pg_monitor`.
|
|
50
|
+
- Out of scope by design: application-schema migrations, ORM management, logical
|
|
51
|
+
backup/restore orchestration, and any bulk destructive DDL.
|
|
52
|
+
- Missing a view, metric, or maintenance command? Open an issue or PR.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Disclaimer
|
|
4
|
+
|
|
5
|
+
Community-maintained open-source project. **Not affiliated with, endorsed by, or
|
|
6
|
+
sponsored by the PostgreSQL Global Development Group or any vendor.**
|
|
7
|
+
"PostgreSQL" and related trademarks belong to their respective owners. Source is
|
|
8
|
+
publicly auditable under the MIT license.
|
|
9
|
+
|
|
10
|
+
## Reporting Vulnerabilities
|
|
11
|
+
|
|
12
|
+
Report privately via a GitHub Security Advisory on
|
|
13
|
+
[github.com/AIops-tools/Postgres-AIops](https://github.com/AIops-tools/Postgres-AIops/security/advisories)
|
|
14
|
+
or email zhouwei008@gmail.com. Please do not open public issues for security
|
|
15
|
+
reports.
|
|
16
|
+
|
|
17
|
+
## Security Design
|
|
18
|
+
|
|
19
|
+
### Credential Management
|
|
20
|
+
- Per-target PostgreSQL role passwords live **encrypted** in
|
|
21
|
+
`~/.postgres-aiops/secrets.enc` (Fernet/AES-128 + scrypt-derived key; chmod
|
|
22
|
+
600), never in `config.yaml` and never in source. The master password is never
|
|
23
|
+
stored — only a per-store random salt and the ciphertext are on disk.
|
|
24
|
+
- A legacy plaintext env var `PG_<TARGET_NAME_UPPER>_PASSWORD` is still honoured
|
|
25
|
+
as a fallback with a deprecation warning (migrate with `postgres-aiops secret
|
|
26
|
+
migrate`).
|
|
27
|
+
- The password is passed to `psycopg.connect` at connect time and held only in
|
|
28
|
+
memory. It is never logged or echoed; `config.yaml` holds only host, port,
|
|
29
|
+
dbname, user, and `sslmode`. The redacted DSN (`dsn_redacted`) masks it.
|
|
30
|
+
|
|
31
|
+
### SQL-Injection Defenses
|
|
32
|
+
- **All values are bound query parameters** (pids, thresholds, limits, setting
|
|
33
|
+
values) — never string-formatted into SQL.
|
|
34
|
+
- The few identifiers that cannot be parameterised (table/index/schema names, GUC
|
|
35
|
+
names, `ORDER BY` columns, index methods, `REINDEX` kinds) are validated
|
|
36
|
+
against strict allow-lists (`postgres_aiops.ops._util`) and double-quoted
|
|
37
|
+
before the single interpolation site; anything that is not a plain identifier
|
|
38
|
+
is rejected, not interpolated.
|
|
39
|
+
- `EXPLAIN` rejects multi-statement input (an embedded `;` is refused).
|
|
40
|
+
|
|
41
|
+
### Governed Operations
|
|
42
|
+
Every MCP tool runs through the bundled `@governed_tool` harness
|
|
43
|
+
(`postgres_aiops.governance`):
|
|
44
|
+
- **Audit** — every call logged to a local SQLite DB under `~/.postgres-aiops/`
|
|
45
|
+
(relocatable via `POSTGRES_AIOPS_HOME`), agent-attributed, secret-redacted.
|
|
46
|
+
- **Token/runaway budget** — hard ceilings (`POSTGRES_MAX_TOOL_CALLS` /
|
|
47
|
+
`POSTGRES_MAX_TOOL_SECONDS` — the env-var names the bundled harness reads) plus
|
|
48
|
+
an on-by-default guard that trips a tight poll/retry loop.
|
|
49
|
+
- **Graduated risk tiers** — `~/.postgres-aiops/rules.yaml` `risk_tiers` gate
|
|
50
|
+
writes by environment/tag; the highest tiers require a recorded approver
|
|
51
|
+
(`POSTGRES_AUDIT_APPROVED_BY` / `POSTGRES_AUDIT_RATIONALE`).
|
|
52
|
+
- **Undo-token recording** — reversible writes fetch the **real before-state
|
|
53
|
+
first** and record a faithful inverse (`create_index`↔`drop_index`, where drop
|
|
54
|
+
captures `pg_get_indexdef`; `update_setting` restores the prior value).
|
|
55
|
+
|
|
56
|
+
### State-Changing Operations
|
|
57
|
+
Every write supports `--dry-run` (CLI) / `dry_run=True` (MCP) and requires double
|
|
58
|
+
confirmation at the CLI layer. Destructive/irreversible ops (`terminate_backend`,
|
|
59
|
+
`cancel_query`, `drop_index`) are `risk_level=high`; mutating maintenance ops
|
|
60
|
+
(`run_vacuum`, `run_analyze`, `create_index`, `reindex`, `update_setting`,
|
|
61
|
+
`reset_query_stats`) are `medium`. Irreversible ops capture prior stats for the
|
|
62
|
+
audit record but record no undo token. `ALTER SYSTEM SET` writes
|
|
63
|
+
`postgresql.auto.conf` and reports (but does not auto-run) the required
|
|
64
|
+
`pg_reload_conf()` / restart.
|
|
65
|
+
|
|
66
|
+
### SSL/TLS
|
|
67
|
+
`sslmode` follows libpq semantics (default `prefer`); set `require`/`verify-full`
|
|
68
|
+
for untrusted networks.
|
|
69
|
+
|
|
70
|
+
### Prompt-Injection Protection
|
|
71
|
+
All catalog- and query-returned text (query text, object names, descriptions) is
|
|
72
|
+
passed through a `sanitize()` truncate + control-character strip before reaching
|
|
73
|
+
the agent.
|
|
74
|
+
|
|
75
|
+
### Network Scope
|
|
76
|
+
No webhooks, no telemetry, no outbound calls beyond the configured PostgreSQL
|
|
77
|
+
connection. No post-install scripts or background services.
|
|
78
|
+
|
|
79
|
+
## Static Analysis
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
uvx bandit -r postgres_aiops/ mcp_server/
|
|
83
|
+
uv run ruff check .
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Supported Versions
|
|
87
|
+
|
|
88
|
+
The latest released version receives security fixes. This is a preview (0.x);
|
|
89
|
+
pin a version in production.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""MCP server package for postgres-aiops."""
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""Shared MCP server primitives: the FastMCP instance, connection helper,
|
|
2
|
+
error sanitisation, and the ``@tool_errors`` decorator.
|
|
3
|
+
|
|
4
|
+
Tool modules under ``mcp_server/tools/`` import ``mcp`` from here and register
|
|
5
|
+
their ``@mcp.tool()`` functions onto it. ``mcp_server/server.py`` then imports
|
|
6
|
+
those modules and runs the server.
|
|
7
|
+
|
|
8
|
+
Keep ``Optional[X]`` (never PEP 604 ``X | None``) in any FastMCP-reflected
|
|
9
|
+
tool signature — on older mcp/pydantic the union eval'd to ``types.UnionType``
|
|
10
|
+
crashes FastMCP's ``issubclass`` check.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import functools
|
|
14
|
+
import logging
|
|
15
|
+
import os
|
|
16
|
+
from collections.abc import Callable
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import Any, Optional
|
|
19
|
+
|
|
20
|
+
from mcp.server.fastmcp import FastMCP
|
|
21
|
+
|
|
22
|
+
from postgres_aiops.config import load_config
|
|
23
|
+
from postgres_aiops.connection import ConnectionManager, PgError
|
|
24
|
+
from postgres_aiops.governance import sanitize
|
|
25
|
+
|
|
26
|
+
logger = logging.getLogger(__name__)
|
|
27
|
+
|
|
28
|
+
_DOCTOR_HINT = "Run 'postgres-aiops doctor' to verify connectivity and credentials."
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _safe_error(exc: Exception, tool: str) -> str:
|
|
32
|
+
"""Return an agent-safe error string; log full detail server-side only."""
|
|
33
|
+
logger.error("Tool %s failed", tool, exc_info=True)
|
|
34
|
+
_passthrough = (
|
|
35
|
+
ValueError,
|
|
36
|
+
FileNotFoundError,
|
|
37
|
+
KeyError,
|
|
38
|
+
PermissionError,
|
|
39
|
+
TimeoutError,
|
|
40
|
+
ConnectionError,
|
|
41
|
+
PgError,
|
|
42
|
+
)
|
|
43
|
+
if isinstance(exc, _passthrough):
|
|
44
|
+
return sanitize(str(exc), 300)
|
|
45
|
+
return f"{type(exc).__name__}: operation failed."
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def tool_errors(shape: str = "dict") -> Callable:
|
|
49
|
+
"""Wrap a tool body in the canonical try/except → ``_safe_error`` pattern.
|
|
50
|
+
|
|
51
|
+
Place this *between* ``@governed_tool`` and the function so the audit
|
|
52
|
+
decorator and FastMCP still see the original signature.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def decorator(func: Callable) -> Callable:
|
|
56
|
+
name = func.__name__
|
|
57
|
+
|
|
58
|
+
@functools.wraps(func)
|
|
59
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
60
|
+
try:
|
|
61
|
+
return func(*args, **kwargs)
|
|
62
|
+
except Exception as e: # noqa: BLE001 — sanitised below
|
|
63
|
+
msg = _safe_error(e, name)
|
|
64
|
+
if shape == "list":
|
|
65
|
+
return [{"error": msg, "hint": _DOCTOR_HINT}]
|
|
66
|
+
if shape == "str":
|
|
67
|
+
return f"Error: {msg} {_DOCTOR_HINT}"
|
|
68
|
+
return {"error": msg, "hint": _DOCTOR_HINT}
|
|
69
|
+
|
|
70
|
+
return wrapper
|
|
71
|
+
|
|
72
|
+
return decorator
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
mcp = FastMCP(
|
|
76
|
+
"postgres-aiops",
|
|
77
|
+
instructions=(
|
|
78
|
+
"Governed PostgreSQL DBA operations (preview): a one-shot cluster "
|
|
79
|
+
"'overview'; server reads (version/settings/extensions/databases/roles); "
|
|
80
|
+
"activity (sessions, long-running queries, locks); query stats "
|
|
81
|
+
"(pg_stat_statements top-N, EXPLAIN); index and table health (unused / "
|
|
82
|
+
"missing / bloat / autovacuum); replication (lag, slots, WAL); three "
|
|
83
|
+
"flagship analyses — 'slow_query_rca', 'bloat_and_vacuum_analysis', and "
|
|
84
|
+
"'blocking_lock_chain_rca'; and guarded writes (terminate/cancel, "
|
|
85
|
+
"vacuum/analyze, create/drop index, reindex, ALTER SYSTEM). Every tool "
|
|
86
|
+
"runs through the postgres-aiops governance harness (audit / budget / "
|
|
87
|
+
"risk-tier / undo). Do NOT use for OT/industrial edge — see industrial-aiops."
|
|
88
|
+
),
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
_conn_mgr: Optional[ConnectionManager] = None
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _get_connection(target: Optional[str] = None) -> Any:
|
|
95
|
+
"""Return a PostgreSQL connection, lazily initialising the manager."""
|
|
96
|
+
global _conn_mgr # noqa: PLW0603
|
|
97
|
+
if _conn_mgr is None:
|
|
98
|
+
config_path_str = os.environ.get("POSTGRES_AIOPS_CONFIG")
|
|
99
|
+
config_path = Path(config_path_str) if config_path_str else None
|
|
100
|
+
_conn_mgr = ConnectionManager(load_config(config_path))
|
|
101
|
+
return _conn_mgr.connect(target)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""MCP server wrapping postgres-aiops operations (stdio transport).
|
|
2
|
+
|
|
3
|
+
Thin adapter layer: each ``@mcp.tool()`` function (in ``mcp_server/tools/``)
|
|
4
|
+
delegates to the ``postgres_aiops`` ops package and is wrapped with the
|
|
5
|
+
postgres-aiops ``@governed_tool`` harness (audit / budget / undo / risk-tier).
|
|
6
|
+
|
|
7
|
+
Standalone, self-governed PostgreSQL DBA operations (preview).
|
|
8
|
+
For PostgreSQL servers/clusters via psycopg 3.
|
|
9
|
+
|
|
10
|
+
Source: https://github.com/AIops-tools/Postgres-AIops
|
|
11
|
+
License: MIT
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
|
|
16
|
+
from mcp_server._shared import _safe_error, mcp, tool_errors
|
|
17
|
+
|
|
18
|
+
# Importing the tool modules registers every @mcp.tool() onto the shared
|
|
19
|
+
# `mcp` instance. Order does not matter; each module is self-contained.
|
|
20
|
+
from mcp_server.tools import ( # noqa: F401 — side effects
|
|
21
|
+
activity,
|
|
22
|
+
analysis,
|
|
23
|
+
indexes,
|
|
24
|
+
queries,
|
|
25
|
+
remediation,
|
|
26
|
+
replication,
|
|
27
|
+
server,
|
|
28
|
+
tables,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
__all__ = ["mcp", "main", "_safe_error", "tool_errors"]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def main() -> None:
|
|
35
|
+
"""Run the MCP server over stdio."""
|
|
36
|
+
logging.basicConfig(level=logging.INFO)
|
|
37
|
+
mcp.run(transport="stdio")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""MCP tool modules. Importing each registers its @mcp.tool() functions."""
|