Skip to content

Match inspect_database omit to neon inspect db 3.4.0 - #322

Merged
andrelandgraf merged 3 commits into
mainfrom
feat/inspect-all-databases
Aug 17, 2026
Merged

Match inspect_database omit to neon inspect db 3.4.0#322
andrelandgraf merged 3 commits into
mainfrom
feat/inspect-all-databases

Conversation

@andrelandgraf

@andrelandgraf andrelandgraf commented Aug 16, 2026

Copy link
Copy Markdown
Collaborator

Problem

inspect_database treated a missing databaseName the way the other tools do: connect to the default or first database, and always echo that name back.

neon inspect db 3.4.0 does the opposite. Omit the name and the CLI covers every database on the branch. Pass a name to inspect one.

A model that omits the name, matching the CLI, only sees one database. Locks, bloat, and table sizes in the others never appear.

Diagnosis

The SQL catalog was already shared with the CLI. The handler was the mismatch. It resolved one connection string and assembled a single-database report. The input schema said so:

The name of the database. If not provided, the default neondb or first available database is used.

The new shape follows from three facts.

Database catalogs differ. Compute-wide views (lfc-hit-rate, working-set, replication-slots) return the same rows from every database, so omit runs them once against the first listed database.

The database column is a schema, not a count. Omit adds it even on a one-database branch so a second database does not change the fields.

databaseName in the response means the caller named a database. Omit never echoes it, including compute-wide omit, which still connects through one database. The databases that actually ran are in databases.

A combined row count is not a per-database SQL cap. 25+25 would miss the cap. 24+1 would invent one. The note fires when at least one database's batch hits the SQL LIMIT.

When limit slices the combined rows and a later database disappears from the page, the note names which databases the returned rows still cover.

Interface

Callers who pass databaseName keep the previous row fields and still get databaseName back. The response always includes databases.

Callers who omit databaseName no longer get the default database. That is the CLI match, and it is a breaking change for that path.

Empty databaseName is rejected: databaseName cannot be empty. Omit it to cover every database.

named omit-database omit-compute
Request databaseName set omitted, database-scoped check omitted, compute-wide check
Runs that database every database, sorted by name first listed database
database column no yes, even on one database no
databaseName in response the name absent absent
databases [name] all, sorted [first listed]

Database-scoped checks: table-sizes, index-sizes, unused-indexes, seq-scans, long-running-queries, locks, outliers, calls, vacuum-stats, bloat, subscriptions.

Compute-wide checks: lfc-hit-rate, working-set, replication-slots.

limit (default 50, max 1000) applies to the combined rows after per-database ranking and SQL caps.

Named

{
  "name": "inspect_database",
  "arguments": {
    "projectId": "project-id",
    "check": "table-sizes",
    "databaseName": "neondb"
  }
}
{
  "check": "table-sizes",
  "describe": "Size of each table (including TOAST), largest first (pg_table_size)",
  "projectId": "project-id",
  "branchId": "br-id",
  "databaseName": "neondb",
  "databases": ["neondb"],
  "fields": ["schema", "name", "size"],
  "totalRowCount": 1,
  "rows": [{ "schema": "public", "name": "t", "size": "8 kB" }],
  "truncated": false
}

Omit, database-scoped

{
  "name": "inspect_database",
  "arguments": {
    "projectId": "project-id",
    "check": "table-sizes"
  }
}
{
  "check": "table-sizes",
  "describe": "Size of each table (including TOAST), largest first (pg_table_size)",
  "projectId": "project-id",
  "branchId": "br-id",
  "databases": ["analytics", "neondb"],
  "fields": ["database", "schema", "name", "size"],
  "totalRowCount": 2,
  "rows": [
    { "database": "analytics", "schema": "public", "name": "a", "size": "8 kB" },
    { "database": "neondb", "schema": "public", "name": "b", "size": "8 kB" }
  ],
  "truncated": false
}

Same shape on a one-database branch: no databaseName, fields still start with database.

When limit drops a later database from the page:

Showing the first 50 of 120 rows, which cover only the databases analytics and neondb (of 3). Raise `limit` to reach the rest.

An all-empty omit uses the all-database empty message, for example No locks held in any database.

A SQL cap on omit:

The `bloat` check returns at most 25 rows per database, and at least one database hit that cap, so there may be more. Use `run_sql` for the full ranking.

Named SQL-cap wording is unchanged: at most 25 rows, and hit that cap.

Omit, compute-wide

{
  "name": "inspect_database",
  "arguments": {
    "projectId": "project-id",
    "check": "replication-slots"
  }
}
{
  "check": "replication-slots",
  "describe": "Replication slots (compute-wide): kind, status, client, restart/confirmed-flush LSNs, and lag (pg_replication_slots + pg_stat_replication)",
  "projectId": "project-id",
  "branchId": "br-id",
  "databases": ["other_db"],
  "fields": [
    "slot_name",
    "slot_type",
    "slot_kind",
    "status",
    "client_addr",
    "restart_lsn",
    "confirmed_flush_lsn",
    "replication_lag"
  ],
  "totalRowCount": 0,
  "rows": [],
  "truncated": false,
  "note": "No replication slots found."
}

No databaseName. No database column. databases is the one database the check connected through.

Errors

One failing database fails the whole run. On a multi-database branch the error names that database and how to narrow:

The "outliers" check needs the "pg_stat_statements" extension, which is not installed on database "neondb". Installing it writes to the user's database, so ask the user first, then run `CREATE EXTENSION IF NOT EXISTS pg_stat_statements;` with run_sql. Pass databaseName to try a database that already has the "pg_stat_statements" extension.
Could not connect to Postgres (database analytics). Pass databaseName to connect through a different database.
missing neon (database analytics). Pass databaseName to inspect one database.

A one-database branch does not get the Pass databaseName hint. Named-database errors keep their previous text.

Also in here

  • README, the inspect_database tool description, smoke-test notes, and CHANGELOG document the omit contract.
  • lfc-hit-rate, working-set, and replication-slots describe strings now say compute-wide.
  • The catalog pin comment moves from d0c84e3 to 5abe208.
  • Live e2e cases that previously omitted databaseName now pass databaseName: "neondb" so they still cover the named path.

Verification

Unit, integration, protocol e2e, and live e2e were run on this branch. Website Playwright e2e was not.

  • named keeps the previous row fields and returns databaseName
  • omit database-scoped covers every database, sorted, and adds database even on one database
  • omit compute-wide picks the first listed database and does not return databaseName
  • empty databaseName is rejected
  • empty branch is rejected
  • limit applies to the combined rows and names the databases still on the page when a later one is sliced off
  • 25+25 is a per-database SQL cap; 24+1 is not a cap
  • named SQL-cap wording is unchanged
  • all-empty omit uses emptyMessageAll
  • omit errors name the database the tool chose; named errors are unchanged
  • extension failures suggest databaseName; connection errors do not get the extension hint
  • compute-wide omit failures say to connect through a different database
  • listed tool schema describes omit

Live e2e: omit table-sizes on a one-database branch, omit locks across two databases, omit replication-slots against the first listed database, and omit outliers failing the run when a later database is missing pg_stat_statements.

For your attention

  • Omit is a breaking change for callers that left databaseName off to get the default database.
  • A failure discards rows already collected from earlier databases.
  • Compute-wide omit uses API list order. Database-scoped omit sorts by name. The first listed database is not necessarily neondb.
  • The named path does not list branch databases. An unknown name still fails at connect time.

Omitting databaseName now covers every API-listed database instead of defaulting to one.
@vercel

vercel Bot commented Aug 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
mcp-server-neon Ignored Ignored Preview Aug 16, 2026 1:00pm

Request Review

databaseName is only echoed when the caller passed it, so a compute-wide omit cannot be copied into the next call.
@andrelandgraf
andrelandgraf merged commit ea9259a into main Aug 17, 2026
6 checks passed
@andrelandgraf
andrelandgraf deleted the feat/inspect-all-databases branch August 17, 2026 05:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants