{
  "markdown": "# rolepod-dblab\n\n**Data-layer safety + truth verifier for AI coding agents.** An MCP server that gives a coding agent *eyes + safe hands on a live database*: prove a migration applied, assert DB state as verify-evidence, read query plans, detect schema drift (code vs DB), and mutate data behind a transaction-confirm guard.\n\nIt is **not** a generic SQL client. Running ad-hoc `SELECT`s belongs to `psql` or an off-the-shelf Postgres MCP. dblab's value is the things nothing else does safely: **guarded mutation, schema-drift detection, and DB state as PASS/FAIL evidence.**\n\ndblab is the **data-layer limb** of the [rolepod](https://github.com/nuttaruj) ecosystem, alongside `rolepod-uiproof` (web/mobile UI) and `rolepod-wplab` (WordPress). v1 is Postgres-only.\n\n---\n\n## The five tools / skills\n\n| Skill | Tool | Phase | What it does |\n|---|---|---|---|\n| `/db-introspect` | `rolepod_db_introspect` | Plan / Debug | Schema, columns, types, indexes, FK graph, row-count estimates → normalized snapshot. Read-only. |\n| `/db-query` | `rolepod_db_query` | Verify | Run a read-only query (inside `BEGIN TRANSACTION READ ONLY`) and return a structured **PASS/FAIL** assertion — not raw rows. |\n| `/db-explain` | `rolepod_db_explain` | Perf / Review | `EXPLAIN [ANALYZE]` → parsed plan flagging sequential scans and probable missing indexes. |\n| `/db-migrate-verify` | `rolepod_db_migrate_verify` | Ship / Review | Diff **SQLAlchemy models vs live schema** → drift report (missing/extra column, nullability, type mismatch). |\n| `/db-write` | `rolepod_db_write` | Build | Guarded mutation: **preview → confirm → commit/rollback**. The only tool that writes. |\n\n### The write-guard ritual (the differentiator)\n\n`db-write` never writes without an explicit confirm. It holds a transaction open across tool calls:\n\n1. **preview** → `BEGIN`, run the statement inside the transaction, return affected-row count + an optional before/after sample + a `txn_id`. **Nothing is committed.**\n2. **confirm** → `COMMIT` (needs the `txn_id`).\n3. **rollback** → `ROLLBACK`. An abandoned transaction auto-rolls-back after the idle timeout (default 5 min, `ROLEPOD_DBLAB_TXN_IDLE_MS`).\n\nHolding a transaction open across turns is why dblab is an MCP plugin and not a prompt-only skill — a skill cannot enforce the confirm gate.\n\n---\n\n## Quickstart (standalone)\n\ndblab works in any MCP-capable CLI with just a connection string — no rolepod core required.\n\n```bash\n# Health check (Node, pg, python3 + SQLAlchemy for drift)\nnpx -y @rolepod/dblab doctor\n\n# Smoke-test a connection\nnpx -y @rolepod/dblab test-connection \"postgresql://user:pass@localhost:5432/mydb\"\n```\n\nRegister the MCP server (the repo ships per-CLI manifests):\n\n- **Claude Code / generic MCP:** `.mcp.json` → `npx -y @rolepod/dblab`\n- **Codex:** `.codex-plugin/plugin.json`\n- **Cursor:** `.cursor-plugin/plugin.json`\n- **Gemini CLI:** `gemini-extension.json`\n\n`pg` is a hard dependency (every skill except drift needs it). `python3` + `SQLAlchemy` are needed **only** for `/db-migrate-verify`; the other four skills work without them.\n\n### Schema drift (`/db-migrate-verify`)\n\nThe dblab server is TypeScript and can't import Python objects in-process, so it shells out to a tiny Python sidecar (`reflect_models.py`) that reflects your SQLAlchemy `Base.metadata` → JSON; the TS server owns the diff. This is the direct analog of how `rolepod-uiproof` shells out to Appium for the mobile runtime it can't reach natively.\n\n```jsonc\n// /db-migrate-verify\n{ \"conn\": \"postgresql://…/db\", \"models_entrypoint\": \"app.models:Base\", \"project_dir\": \"/path/to/project\" }\n```\n\nFallback modes: **native** (reflect the models) → **snapshot** (`snapshot_path` to a pre-generated JSON) → **unverifiable** (clear reason, never a false PASS).\n\n---\n\n## Scope boundary (no-overlap)\n\ndblab deliberately does **not** duplicate the rest of the ecosystem:\n\n| Capability | Owner |\n|---|---|\n| Safe mutation (txn preview → confirm), schema drift, DB state as PASS/FAIL | **dblab** ✅ |\n| WordPress DB via WP semantics (options, transients, `wpdb`) | **rolepod-wplab** |\n| Browser / native-mobile UI runtime | **rolepod-uiproof** |\n| Schema *design* decisions | the architect agent (dblab verifies, never designs) |\n| DB provisioning / scaling / backup | a cloud MCP (Railway / Vercel) |\n\n**Routing seam:** target is a **WordPress site** → `wplab`; **any other database** (SaaS backend Postgres, analytics DB) → `dblab`.\n\n---\n\n## Compose with rolepod (by reference, optional)\n\nWhen the parent `rolepod` plugin is present (detected via the marker file `<git-root>/.rolepod/parent-active`), dblab routes evidence to `<git-root>/.rolepod/evidence/` with a `manifest.json` per Extension Protocol v1. The composition is **additive — dblab never blocks or caps anything; rolepod skills opt in:**\n\n- **`check-work`** → DB becomes a first-class evidence type: `/db-query` PASS/FAIL closes the gap in its evidence list (`tests, build, typecheck, curl, logs, screenshot, browser, …, DB`).\n- **`review-code`** → on migration / auth / billing paths, escalate to `/db-migrate-verify`.\n- **`debug-issue`** → inspect live data state (`/db-introspect`, `/db-query`) as a root-cause source.\n- **`finish-work`** → `/db-migrate-verify` as a pre-ship drift gate.\n\nStandalone is the default; the four seams above are documented integration points, wiring is optional in v1.\n\n---\n\n## Development\n\n```bash\nnpm install\nnpm run build       # tsup → dist/ + JSON-schema export\nnpm run typecheck   # tsc --noEmit\nnpm test            # vitest (integration tests need Docker for a throwaway Postgres)\n```\n\nSee [CHANGELOG.md](./CHANGELOG.md) and [THIRD_PARTY.md](./THIRD_PARTY.md). MIT licensed.\n",
  "bytes": 5676,
  "sha": "beb18f4ff5d307d2995229e3da4f32c883fa9f65fc26cab89e3f5c214da6e4b3",
  "repo_slug": "nuttaruj/rolepod-dblab",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_nuttaruj_rolepod_dblab_14be355d/readme"
}