Skip to main content
Glama
igorolv

jdbc-mcp-server

JDBC MCP Server

CI Release License Java 21 MCP

A local MCP server for read-only access to PostgreSQL, Oracle, and Microsoft SQL Server databases. It lets AI agents such as Claude Code, Cursor, VS Code Copilot, and others write SQL queries, inspect execution plans, and explore database structure: tables, columns, indexes, foreign keys, views, functions, and sequences.

PostgreSQL, Oracle, and Microsoft SQL Server JDBC drivers are bundled into the fat jar, so no extra driver installation is required.

The server exposes 49 MCP tools and can optionally expose catalog-qualified MCP resources for table and column metadata. Tools may update the local SQLite catalog, but they never write to the inspected PostgreSQL, Oracle, or SQL Server database.

One server process can serve several databases: name them in connections.json and pass connection to any tool. The tool manifest stays a single set regardless of how many databases are configured, and pools are opened only for the databases actually used.

Quickstart

1. Get the jar — download jdbc-mcp-server.jar from the latest release (JDK 21+ required; all JDBC drivers are bundled), or build it yourself:

./gradlew bootJar   # → build/libs/jdbc-mcp-server.jar

2. Describe your databases in ~/.jdbc-mcp-server/connections.json:

{
  "connections": {
    "myapp": {
      "url": "jdbc:postgresql://db.example.com:5432/myapp",
      "username": "ai_readonly",
      "password": "secret",
      "description": "Application database — customers, orders, shipments"
    }
  }
}

Use a read-only database user; five minutes there outweighs every other protection in this server.

3. Register the server with your MCP client — with no database settings in the client config:

{
  "command": "java",
  "args": ["-jar", "<absolute-path>/jdbc-mcp-server.jar"],
  "env": {}
}

For Claude Code that is one command:

claude mcp add --scope user jdbc java -jar /path/to/jdbc-mcp-server.jar

4. Ask the agent for listConnections. It answers with the databases this server serves; every other tool takes that name as its first argument:

{"connection": "myapp", "sql": "SELECT count(*) FROM orders"}

Full details: Databases and Credentials, Connecting an AI Client, Serving Several Databases from One Server.

Related MCP server: mcp-multi-db

Databases and Credentials

Every database this server serves is described in one JSON file. Nothing about a database — URL, credentials, schema, timeouts, limits — comes from the environment.

The connections file

Default path ~/.jdbc-mcp-server/connections.json (<data-dir>/connections.json), overridden with JDBC_MCP_CONNECTIONS_FILE. When the file is missing or defines no connection the server still starts (so an MCP client can list its tools), logs a warning, and listConnections returns an empty list; every other tool then reports that no connection is available. A file that is present but malformed is a startup error.

{
  "connections": {
    "orders": {
      "url": "jdbc:postgresql://db.example.com:5432/orders",
      "username": "ai_readonly",
      "password": "secret",
      "defaultSchema": "public",
      "description": "Order service — customers, orders, shipments",
      "structureSnapshotSchemas": ["public", "nsi"]
    },
    "billing": {
      "url": "jdbc:oracle:thin:@//oracle.example.com:1521/BILLING",
      "username": "AI_READONLY",
      "password": "${BILLING_DB_PASSWORD}",
      "description": "Legacy billing (Oracle)"
    }
  }
}

The object key is the connection name. It is also the name of the connection's local catalog directory (<data-dir>/<name>/) and appears in MCP resource URIs, so it must match [A-Za-z0-9._-]+(@[A-Za-z0-9._-]+)?, be at most 64 characters, and not be . or ...

The optional @ is there to name the two axes separately: <service>@<stand>, as in ssj@dev, nsi@dev, ssj@tst. A dash cannot do that job, because dashes already occur inside service names (ssj-ws, ssj-ek-export, ais-ui), so ssj-ws-dev is ambiguous to a human and to a model alike. @ never occurs in a service name and reads as "what, where" the way user@host does. It is percent-encoded to %40 in resource URIs; nothing else about the name changes — the directory on disk is the name as written.

url is the only required field; the engine is detected from its prefix (jdbc:postgresql:, jdbc:oracle:, jdbc:sqlserver:). description is free text returned by listConnections, so an agent can pick a database by meaning rather than by name — worth filling in.

Any string value may reference an environment variable as ${VAR}. A referenced variable that is not set fails startup with a message naming the variable and the field; it never becomes an empty password. Read the next section before reaching for it.

Why credentials live in a file, not in environment variables

The point of this server is that the agent reaches the database only through it: every statement goes through the read-only guard, every result is capped by maxRows, and nothing but SELECT / WITH / EXPLAIN gets through.

Credentials in environment variables undermine exactly that. They are set on the server process by the MCP client, which means they also sit in the client's own configuration — a file agents read and edit as a matter of routine — and in the environment of whatever shell launched it. An agent that has seen a URL, a user and a password does not need the tools any more: psql, sqlplus, sqlcmd or three lines of Python connect straight to the database, with no guard, no row cap and no trace in this server's log.

So the server accepts no database credentials from the environment at all — there are no JDBC_URL / JDBC_USERNAME / JDBC_PASSWORD variables. They live in connections.json, which only the server reads.

Be clear about what that does and does not buy:

  • It removes the easy path. Credentials stop being part of the material an agent routinely handles: MCP client configs, shell environment, env dumps in logs and bug reports.

  • It is not a sandbox. An agent with shell access running as you can read the file; chmod 600 keeps out other users, not a process running as your user.

  • The guarantee that survives everything is a read-only database user. The file narrows the attack surface; the database's own permissions close it.

For the same reason, prefer a literal password in the file over a ${VAR} reference whose variable would be set in the MCP client's env block — that puts the secret straight back where the agent looks. ${VAR} earns its place when the value is injected from outside the agent's reach (a systemd unit, a wrapper script, a secret manager), or when the file itself is shared or committed and the secret must not be.

Connection fields

Everything except url is optional; a field left out falls back to the built-in default:

Field

Default

Meaning

url

required

JDBC URL; also selects the engine

username, password

none

Database credentials

description

none

Free text returned by listConnections

defaultSchema

the session schema

Schema used when a metadata tool call omits one

queryTimeoutSeconds

30

Per-query timeout; 0 disables

maxRows

1000

Row cap for one response; truncated: true when hit

fetchSize

500

JDBC fetchSize hint

readonlyGuard

strict

off disables the client-side SELECT-only check

poolMaximumSize

40

Hikari maximum pool size

poolMinimumIdle

0

Hikari minimum idle; 0 keeps the pool lazy

poolConnectionTimeoutMs

10000

Hikari connection checkout timeout

poolValidationTimeoutMs

5000

Hikari validation timeout

poolIdleTimeoutMs

60000

Idle connections above poolMinimumIdle are closed after this

structureSnapshotSchemas

the default schema

Schemas captured by rebuildCatalog

structureSnapshotOracleColumnQueryTimeoutSeconds

300

Oracle-only timeout for the bulk column query during rebuildCatalog; 0 disables

usageCatalogEnabled

true

When false, usage tools report the disabled state

usageCatalogPaths

none

Extra directories, JSON files or zip archives with QueryUsage records

usageNativeSchemas

the default schema

Schemas scanned for native usage

usageNativeIncludeViews, usageNativeIncludeRoutines, usageNativeIncludeTriggers

true

What native usage scanning covers

usageNativeMaxObjects

10000

Maximum native usage records per index build

The JDBC_MCP_TOOLS_* group flags stay in the environment — they shape the tool manifest, which is shared by all connections. See Configuration for the handful of variables the server itself reads.

URL examples

jdbc:postgresql://db.example.com:5432/myapp
jdbc:postgresql://db.example.com:5432/myapp?currentSchema=public&sslmode=require

jdbc:oracle:thin:@//db.example.com:1521/ORCLPDB1
jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=...)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=...)))

jdbc:sqlserver://db.example.com:1433;databaseName=myapp;encrypt=true;trustServerCertificate=false
jdbc:sqlserver://db.example.com;databaseName=myapp;integratedSecurity=false

Why This Exists

Scenario: you ask an LLM to "check the database and show how many orders we had by status last month." Without this server, the LLM may:

  • invent table and column names;

  • miss the real schema details, such as nullable fields, types, and foreign keys;

  • accidentally generate a DELETE or TRUNCATE while "reasoning."

With this server, the LLM can:

  1. call schemaBrief to discover the schema map, or queryContext to get ready-to-use detailed context: tables, columns, relationships, and constraints;

  2. refine the context with tableContext around a specific table or findJoinPaths for JOIN path discovery;

  3. write a query and optionally call inspectQuery, queryLint, or resolveQueryLineage for AST, metadata, and view/routine lineage checks;

  4. call validateQuery with the same params or namedParams that will be used for execution, validating syntax without running the query;

  5. call explainQuery when a plan is needed;

  6. call executeQuery to fetch data.

Any non-SELECT query is blocked before it reaches the database.

Beyond live schema introspection, the server also keeps a local usage catalog of known SQL queries used by applications and reports against the inspected database, together with their business context — parameter meanings, output column descriptions, and where each output is rendered (Excel cell, dashboard widget, BI Publisher region). This lets the LLM answer questions like "which production reports already touch this column?" and "what business label does this field have in the customer card?" against a curated body of evidence instead of guessing from names alone. The catalog is also the source of the typed three-layer evidence bundle on relationship edges, so undeclared joins observed in production queries are treated as first-class hints alongside declared FKs. See Usage Catalog below.

Architecture

                                                  +------------+
                                            +---> | database A |
+-------------+     stdio      +----------+ |     +------------+
|  AI agent   | <------------> | jdbc-mcp | |     +------------+
| (Claude Code|  stdin/stdout  |  server  |-+---> | database B |
|  Cursor...) |                |  (Java)  | |     +------------+
+-------------+                +----------+ |
                                            +---> ...

                                          read-only JDBC
                                          PG / Oracle / SQL Server

The protocol is stdio only. The client starts the server as a child process. One process serves any number of named databases, all declared in the connections file; a connection's pool is opened the first time a tool call names it.

MCP Resources

When JDBC_MCP_RESOURCES_ENABLED=true, the server exposes — for every configured connection that already has a local catalog file — a concrete catalog manifest, one concrete resource for every table or view already persisted in that connection's structure snapshot, and two parameterized resource templates:

jdbc-mcp://catalog/<catalog>/manifest
jdbc-mcp://catalog/<catalog>/schemas/SSV/tables/CUSTOMERS
jdbc-mcp://catalog/<catalog>/schemas/{schema}/tables/{table}
jdbc-mcp://catalog/<catalog>/schemas/{schema}/tables/{table}/columns/{column}

<catalog> is the percent-encoded connection name. It is fixed per connection when the server starts and is not a template variable clients can use to switch databases: a read resolves the connection from the URI it was given. This keeps resource URIs unambiguous both across the connections of one server and across several registered instances of this jar. The manifest reports database kind, snapshot version/build time/covered schemas, and the exact templates for its catalog. Table and column reads reuse MetadataService, so they have the same persistent-snapshot and live-fallback semantics as describeTable.

Concrete table resources are loaded from the local SQLite snapshots when the MCP server starts — no database is contacted and no JDBC pool is created for this — so clients with MCP resource-picker support can offer entries like SSV.CUSTOMERS without querying the live database. Their compact descriptions contain the database comment when present, the primary-key columns, and outgoing foreign-key mappings; column lists and counts are intentionally omitted. After running rebuildCatalog in an already-running server, restart or reconnect that MCP server instance to refresh its concrete resource list.

Column resources include the column definition plus matching PK position, unique constraints, indexes, outgoing/incoming foreign keys, and CHECK constraints. URI path segments preserve case and use UTF-8 percent encoding. Resources are disabled by default; enabling them leaves the MCP tools unchanged.

MCP Tools

The 49 tools are grouped below by purpose.

Every tool takes connection as its first, required argument, naming the database to run against — including installations that serve exactly one database. listConnections lists the names. See Serving Several Databases from One Server.

Tool Groups

Tools are organised into groups that can be turned on or off independently with JDBC_MCP_TOOLS_* flags. All groups are on by default, so the full tool set is available out of the box. Turning groups off shrinks the tools/list manifest, which matters for small-context (local) models that would otherwise be flooded with tool schemas before the first call.

Group

Flag

Default

Tools

Metadata

JDBC_MCP_TOOLS_METADATA

on

listSchemas, listTables, describeTable, getTriggerDefinition, getViewDefinition, listRoutines, getRoutineDefinition, listSequences, searchObjects

Query

JDBC_MCP_TOOLS_QUERY

on

executeQuery

Admin

JDBC_MCP_TOOLS_ADMIN

on

rebuildCatalog

Sample

JDBC_MCP_TOOLS_SAMPLE

on

sampleRows

Query analysis

JDBC_MCP_TOOLS_ANALYSIS

on

explainQuery, analyzePlan, validateQuery, inspectQuery, queryLint, resolveQueryLineage

Distribution

JDBC_MCP_TOOLS_DISTRIBUTION

on

columnStats, columnDistribution, columnHistogram, nullRatio, estimateSelectivity, joinCardinality

Statistics

JDBC_MCP_TOOLS_STATS

on

tableStats, indexStats, unusedIndexes, redundantIndexes, fkIndexCoverage

Benchmark

JDBC_MCP_TOOLS_BENCHMARK

on

benchmarkQuery, timedQuery

Usage catalog

JDBC_MCP_TOOLS_USAGE

on

usageCatalogStatus, getQuery, listQueries, findQueriesByTable, findQueriesByColumn, observedRelationships, listKnownTags, listKnownDomains, listKnownKinds, invalidateUsageCatalogCache

Schema context

JDBC_MCP_TOOLS_SCHEMA_CONTEXT

on

tableContext, findJoinPaths, schemaLint, schemaBrief, schemaGraph, queryContext, schemaGraphDot

Connections

JDBC_MCP_TOOLS_CONNECTIONS

on

listConnections

Each flag accepts true / false. For a small-context local model, turn off the groups you do not need — for example keep only Metadata + Query by setting the rest to false — to cut the manifest down to a minimal "explore the schema and run a query" set. The sections below describe each tool regardless of its group.

Query

Tool

Description

executeQuery

Execute a SELECT, WITH, or EXPLAIN statement. Parameters: sql, params (array for ?) or namedParams (object for :name), limit, timeoutSeconds. The result is marked with truncated: true if the row limit is hit

explainQuery

Return the execution plan. PostgreSQL: EXPLAIN (FORMAT TEXT). Oracle: EXPLAIN PLAN FOR plus DBMS_XPLAN.DISPLAY. SQL Server: SET SHOWPLAN_TEXT ON on the same session. Parameters can be passed as params (?) or namedParams (:name). analyze=true on PostgreSQL enables EXPLAIN ANALYZE; be careful, because the query is actually executed. SQL Server currently returns estimated plans only

analyzePlan

Compact LLM-oriented plan summary instead of a large raw plan dump: highest-cost nodes, full scans on large tables, estimate errors (planner vs. reality, requires analyze=true on PostgreSQL), risky nested loops with large outer input, and disk sort spills. PostgreSQL: EXPLAIN (FORMAT JSON) / EXPLAIN ANALYZE. Oracle: EXPLAIN PLAN plus PLAN_TABLE (analyze is ignored because Oracle provides a static plan here). SQL Server: SET SHOWPLAN_XML ON estimated plan. Parameters can be passed as params (?) or namedParams (:name)

validateQuery

Validate syntax without execution: read-only guard plus driver prepareStatement, with a JSqlParser-derived inspection summary when parsing succeeds. Parameters can be passed as params (?) or namedParams (:name). Useful for LLM self-correction

inspectQuery

Parse SQL through JSqlParser without touching the database and return an AST summary: tables, aliases, CTEs, select items, joins, predicates, order by, columns, parameters, features, and parser warnings

queryLint

Parse SQL and combine the AST with metadata, index, and FK checks. Returns advisory warnings such as unknown tables or columns, SELECT *, joins without conditions, FKs without supporting indexes, and predicate/order-by columns that are not leading index columns. SQL is not executed

resolveQueryLineage

Resolve direct objects referenced by a query and recursively expand database views/materialized views to underlying physical tables. Function/procedure expansion is best-effort: embedded SELECT / WITH statements are extracted from routine source when available. Parameters: sql, schema, expandViews, expandRoutines, maxDepth

Benchmarking

Tools for measuring the real cost of a query, so the LLM does not have to guess from the plan and can see actual milliseconds and buffer counters.

Tool

Description

benchmarkQuery

Run the query coldRuns + warmRuns times (defaults to 1 cold + 3 warm) and return wall-clock min, median, and max for warm runs; cold runs are reported separately. Parameters can be passed as params (?) or namedParams (:name). limit and timeoutSeconds are required; unbounded queries are rejected. Returns the size of the last result (row_count, columns, truncated), not the rows

timedQuery

Regular executeQuery plus wall-clock elapsed_ms. Parameters can be passed as params (?) or namedParams (:name). On PostgreSQL, it also captures pg_stat_statements snapshots before and after the query; the diff shows which query IDs added calls, total_exec_time_ms, rows, shared_blks_hit, and shared_blks_read, making it clear where the server spent time. Requires pg_stat_statements (CREATE EXTENSION pg_stat_statements; plus shared_preload_libraries); if the extension is missing, returns pg_stat_statements.available: false

Metadata

Tool

Description

listSchemas

List schemas. System schemas are hidden by default; use includeSystem=true to show all

listTables

List tables and views in a schema. Parameters: schema, namePattern (with % / _), types (comma-separated, for example TABLE,VIEW,MATERIALIZED VIEW)

describeTable

Full object description in one call: columns, primary key, unique constraints, indexes, outgoing/incoming FKs, CHECK constraints and allowed values, plus compact trigger metadata

getTriggerDefinition

Trigger body for one named trigger. Parameters: schema, table, trigger

getViewDefinition

SQL definition of a view

listRoutines

Functions, procedures, and packages in a schema

getRoutineDefinition

Function or procedure source code. On Oracle, all ALL_SOURCE lines are concatenated in order

listSequences

Sequences in one schema, or across schemas when schema is omitted

searchObjects

Case-insensitive substring search across non-system tables, views, routines, sequences, and synonyms

Schema Context

High-level tools for quick schema orientation and SQL authoring. Instead of manually calling listTables -> describeTable -> sampleRows for each table, an LLM can get ready-to-use context in one call: tables, columns, relationships, constraints, and sample rows.

Tool

Description

tableContext

Context around one table: the table itself, FK parents, and optionally child tables and relationship edges. FK traversal uses the requested depth (default 1, max 4). Parameters: schema, table, depth, includeIncoming, includeStats, includeObserved

findJoinPaths

Find JOIN paths between two tables through FKs. The graph is traversed in both directions and each edge includes joinCondition and a typed evidence bundle (see Edge evidence below). Parameters: fromSchema / fromTable, toSchema / toTable, maxDepth (default/max 4), maxPaths (default 5, max 25), scanLimit (default/max 300), includeObserved

schemaBrief

Plain-text full-schema map for SQL authoring: all matching tables/views with column counts, PK, incoming/outgoing relationship counts, key-like columns, central/isolated tables, and capped key FK relationships. Use this first when relevant tables are unknown; follow with queryContext for detailed context. Parameters: schema, terms (optional substring search), maxTables (safety cap; default 2000, max 5000)

schemaGraph

Schema relationship graph metrics: nodes with in/out degree and classification, edges, central tables, isolated tables, connected components, and cycle hints. Optionally includes the shortest path between two tables

schemaLint

Schema lint audit: missing primary keys, FKs without indexes, FK type mismatches, nullable unique constraints, status/type columns without CHECK constraints, orphan *_id columns, missing remarks, isolated tables, and wide tables. Checks are configurable through checks

queryContext

Build compact SQL-authoring context from search terms and/or explicit tables. Finds relevant tables and columns using declared schema names/comments plus usage-catalog semantic evidence when available, includes constraints and allowed values, relationships and JOIN paths between selected tables, and optionally sample rows (up to 3 per table)

schemaGraphDot

DOT/Graphviz representation of the schema relationship graph. Nodes are tables with all columns and types (PK and FK marked inline), edges include JOIN conditions. Parameters: schema, tables (optional comma-separated filter)

Edge evidence

When includeObserved is left unset, tableContext / findJoinPaths enable it automatically if the local usage catalog is enabled (see Usage Catalog below). Every relationship edge then carries a typed three-layer evidence bundle. Each layer is independently optional and is omitted when there is no signal:

  • declaredSchema — the relationship is a declared foreign key in the database catalog. Carries the FK name and column lists.

  • observedQuery — the equi-join pair appears in stored application queries. Carries joinSupport (number of distinct queries) and queryUids (up to 5 contributing uids).

  • semanticUsage — terms shared across queries that touch both tables: business domains, business objects, and output labels, plus the co-occurring query count and uid preview. This layer decorates existing edges only — it never proposes new relationships.

{
  "relationshipType": "foreignKey",
  "fromTable": "ORDERS", "fromColumns": ["CUSTOMER_ID"],
  "toTable": "CUSTOMERS", "toColumns": ["ID"],
  "evidence": {
    "declaredSchema": { "foreignKeyName": "FK_ORDERS_CUSTOMER", "fromColumns": ["CUSTOMER_ID"], "toColumns": ["ID"] },
    "observedQuery": { "joinSupport": 18, "queryUids": ["SHOP/InvoiceReport.json#header"] },
    "semanticUsage": {
      "sharedBusinessDomains": [{ "value": "Customers", "support": 12, "queryUids": [...] }],
      "sharedBusinessObjects": [{ "value": "Invoice payer", "support": 4, "queryUids": [...] }],
      "sharedOutputLabels":     [{ "value": "Payer name",   "support": 3, "queryUids": [...] }],
      "coOccurringQueryCount": 22,
      "coOccurringQueryUids": [...]
    }
  }
}

Equi-join pairs seen only in stored queries (no declared FK) are appended as new edges with relationshipType: "observed" and undirected: true, between tables already in scope. Composite (multi-column) FKs receive a declaredSchema layer but no observed-pair match in this iteration. schemaBrief, schemaGraph, and queryContext only surface declared FK relationships.

Evidence model

The schema-context layer keeps three sources of knowledge separate:

  • declared_schema - live database introspection: tables, columns, PK/FK, indexes, constraints, comments and statistics.

  • observed_query - the indexed query catalog: which stored application/report queries reference a table or column, and in which SQL context (select, where, join, order_by, having).

  • semantic_usage - adapter-supplied business meaning: query domains/tags/labels, output labels, parameter descriptions, field usages, rendered business objects and confidence.

In tableContext, the existing table fields are the compact declared_schema view. When includeObserved is enabled and the usage catalog is available, each table also gets an evidence block:

{
  "evidence": {
    "observedQuery": {
      "queryCount": 12,
      "queryUids": ["SHOP/reports/customer-card#main"],
      "columns": [
        {"column": "STATUS", "queryCount": 5, "contexts": [{"value": "where", "support": 4}]}
      ]
    },
    "semanticUsage": {
      "businessDomains": [{"value": "Customers", "support": 8}],
      "businessTags": [{"value": "customer", "support": 6}],
      "queryLabels": [{"value": "Customer card", "support": 3}],
      "outputLabels": [{"value": "Customer name", "support": 4}],
      "businessObjects": [{"value": "Customer card", "support": 3}]
    }
  }
}

The server treats this as evidence, not as a single canonical business model. Different queries may legitimately attach different business roles to the same physical table or column.

queryContext also uses semantic_usage as a discovery signal. When the user passes natural language terms, the server searches usage-catalog domains, tags, query labels, output labels and business objects. Matching tables are returned in semanticMatches and are considered before the fallback name/comment scan over live schema metadata. This lets terms such as "payer" find a physical CUSTOMERS table when existing reports expose customers.name as "Payer name".

Usage Catalog

A catalog of known SQL usage against the inspected database, together with optional business context: parameters with descriptions, output columns with their meaning, and where each output is displayed in the consuming artifact (Excel cell in a BI Publisher report, dashboard widget, etc.).

There are two sources. File-backed usage comes from directories / JSON files / zip archives containing canonical QueryUsage JSON records. Database-native usage is derived automatically from the connected schema's views, routines and triggers. At runtime the server parses these records and builds a persistent SQLite index with extracted tables / columns / equi-join pairs as facts. JSON files remain authoritative for file-backed records; native records are refreshed from live metadata.

Why this exists. The metadata tools answer "what tables and columns exist". The usage catalog answers "how are they actually used by applications". With both, an LLM can replace guesses about undeclared joins with evidence-based reasoning ("these two columns are joined in 17 production reports, here are their uids").

Identity. Each query is keyed by (source.kind, source.path, source.unit). Diagnostics and evidence render this key as:

{source.kind}/{source.path}#{source.unit}

The #unit suffix is omitted when there is no unit. Examples:

bi-publisher-report/reports/customers/CustomerCard.xdo#CUST
manual/manual/ad-hoc-2026-05-01
java-dao/src/main/java/com/example/shop/OrderDao.java#findByCustomer

source.kind and source.unit must not contain / or #; source.path must not contain #. For duplicate source keys, the first record wins for that index build.

Where the files live. The default catalog directory is <data-dir>/<connection>/usage-catalog. Configure usageCatalogPaths on the connection as a list of additional directories, .json files, or .zip archives. Directories are scanned recursively for *.json; zip archives are scanned for JSON entries. Set usageCatalogEnabled: false to disable the catalog. usageCatalogStatus then reports catalogEnabled: false; other public usage tools return an argument error explaining how to enable it.

Database-native usage. The catalog also indexes supported database objects from the default schema:

  • views / materialized views as source.kind="database-view" or source.kind="database-materialized-view";

  • functions and procedures as source.kind="database-function" / source.kind="database-procedure" where the engine reports that distinction;

  • triggers as source.kind="database-trigger".

Views usually contribute fully parsed table, column and join evidence. Routine and trigger bodies are engine-specific, so the indexer first uses an ANTLR-based procedural pre-extractor to find embedded SELECT / WITH / INSERT / UPDATE / DELETE / MERGE statements, then feeds those statements into the existing JSqlParser analysis pipeline. If no embedded statement is found, the object is still kept as a provenance record. Use usageNativeSchemas on the connection to scan explicit schemas.

Persistent index. The server never builds the usage index on startup. The first usage-catalog lookup builds it synchronously from file-backed records and database-native objects into the local SQLite <catalog>.db. Source files and database objects remain authoritative. Use invalidateUsageCatalogCache after changing them; it clears the indexed usage rows and the next lookup rebuilds them.

Local-only writes. The usage catalog never writes to the inspected JDBC database (PostgreSQL / Oracle / SQL Server). The existing ReadOnlyGuard and connection-level protections remain in force.

Typed payload. The canonical source, parameters[], outputs[], fieldUsages[] and nested objects are described by the JSON Schema (field names, types, descriptions, enum values). The same record types (QueryUsage and friends in usage/format/) are used by file indexing.

The canonical source-agnostic JSON format is documented in docs/usage-catalog-format.md; its JSON Schema lives at src/main/resources/schemas/query-usage-record.schema.json, with examples under examples/usage/. Source-specific adapters should emit this canonical shape rather than being implemented inside the JDBC MCP server.

Tool

Description

usageCatalogStatus

Current catalog state (not_started, indexing, ready, failed, or invalidated), enabled flag, and configured sources

invalidateUsageCatalogCache

Drop the runtime index. The next lookup rebuilds it synchronously from configured files and database-native objects

getQuery

Full record selected by sourceKind, sourcePath, and optional sourceUnit: header, parameters, parsed tables/columns/join pairs, outputs, and field usages

listQueries

Paginated listing with optional filters: sourcePath (LIKE — % / _ allowed), sourceKind, businessDomain, tag, parseStatus, searchText, limit, offset

findQueriesByTable

All catalog queries that reference a given table. Case-insensitive matching against alias-resolved, uppercased table names. Optional schema filter

findQueriesByColumn

All catalog queries that reference a given column, with the SQL context of the reference (select / where / join / order_by / having). Optional schema and table filters

observedRelationships

Aggregate observed equi-join pairs across stored queries, grouped by (left_table.left_column = right_table.right_column) with support count and contributing query uids. Non-equi joins (BETWEEN, function-based) are excluded. The same data feeds the observedQuery layer of the relationship evidence bundle in tableContext / findJoinPaths

listKnownTags

Tags currently used in the catalog, with query counts. Lets the agent reuse a stable vocabulary across ingest calls

listKnownDomains

Same for businessDomain values

listKnownKinds

Source-kinds currently used in the catalog with their query counts. Helps the agent discover valid values for listQueries sourceKind filter

Resolution. During indexing, table / column qualifiers are resolved cheaply through the parser's alias map and uppercased for case-insensitive matching. An explicit schema in the SQL (SCHEMA.TABLE) is preserved verbatim. Unqualified table references are resolved as part of the index build against the live JDBC schema: exactly one match fills the schema, multiple matches are marked ambiguous, and zero matches stay unresolved.

Catalog Administration

Tool

Description

rebuildCatalog

Rebuild the persistent structure snapshot and usage index for comma-separated schemas (or the configured/default scope), checkpoint SQLite WAL, and return the distributable <catalog>.db path and the connection it was built for

This tool writes only to the local catalog. It does not modify the inspected database.

Connections

Tool

Description

listConnections

List the databases this server serves: name (the value to pass as connection), description, engine kind, default schema, whether a local catalog file already exists, and whether the pool has been built in this process

listConnections reads configuration and the local filesystem only — it opens no database connection, so it still answers when some of the configured databases are down. In an unfamiliar installation it is the first call worth making.

Persistent Structure Snapshot

Structural metadata (columns, keys, indexes, FKs, views, routines, triggers, sequences) is held in a persistent structure snapshot stored in the local SQLite <catalog>.db file (the same database file as the usage catalog, under <data-dir>/<catalog>/). SQLite runs in WAL mode, so Codex, Claude, and other local agent processes can use the same catalog concurrently. This speeds up repeated calls to tableContext, findJoinPaths, schemaLint, schemaGraph, queryContext, describeTable, searchObjects, and the usage-catalog re-resolver. Statistics tools such as tableStats, indexStats, columnStats, and sampleRows are not cached; their counters are live.

The snapshot is authoritative ("cache forever") — there is no TTL or staleness detection. It is filled lazily (describeTable persists each table it loads) and can be front-loaded for whole schemas with the rebuildCatalog tool, which builds the structure snapshot and the usage index into one distributable <catalog>.db. rebuildCatalog checkpoints the WAL before returning. Clear the catalog while all server processes are stopped by deleting <catalog>.db and any adjacent <catalog>.db-wal / <catalog>.db-shm files.

Existing H2 <catalog>.mv.db files are not converted or deleted. On first SQLite startup the server creates a new <catalog>.db, logs a warning, and leaves the legacy file untouched; run rebuildCatalog to populate the new catalog.

Configuration:

  • structureSnapshotSchemas - schemas to front-load on a full rebuild (empty → the default schema).

  • structureSnapshotOracleColumnQueryTimeoutSeconds - Oracle-only timeout for the DBMS_XMLGEN-backed bulk column/default query during a full rebuild (default 300; 0 disables).

Both are per-connection fields in connections.json.

Data Exploration

Tool

Description

sampleRows

Return a few rows from a table or view (LIMIT / FETCH FIRST / TOP depending on database). Parameters: schema, table, limit (default 10, max 100)

Selectivity and Distribution

Tool

Description

columnStats

Basic column statistics: total_rows, non_null_rows, distinct_values, min, max. A cheap one-shot aggregate when only extremes are needed

columnStats only reports extremes. The other tools answer "how selective is this predicate?" and "how skewed are values in this column?", which is the information an LLM needs to choose an index or rewrite a JOIN meaningfully.

Tool

Description

columnDistribution

Top-N most frequent values of a column plus their share. Surfaces skew, for example 70% of rows with status='OK', where an index on status alone is not useful. Parameters: schema, table, column, topN (default 20, max 1000)

columnHistogram

Percentiles P25 / P50 / P75 / P90 / P95 / P99 plus min, max, and null count. Uses SQL:2003 WITHIN GROUP: percentile_cont for numeric types and percentile_disc for all others, including dates, timestamps, and text

nullRatio

One scan for null / non-null counts across every table column. Columns are sorted by descending null_ratio. sparse=true marks columns where more than 50% of rows are null, which may be candidates for a partial index

estimateSelectivity

Estimate how many rows a predicate would return without executing the query, using EXPLAIN on SELECT 1 FROM t WHERE <predicate>. Returns estimated rows, baseline row count without the filter, and selectivity. Useful for placing the most selective predicate first in a composite index

joinCardinality

Estimate the output row count of a JOIN without executing it. Returns planner estimate, per-side row counts, and selectivity_vs_cartesian. Supports INNER, LEFT, RIGHT, and FULL

Object Statistics

These tools give the LLM object scale and health signals; without that, optimization advice becomes guesswork. Data comes from system catalogs (pg_class, pg_stat_*, ALL_TABLES, ALL_INDEXES, DBA_SEGMENTS) and is aggregated on the Java side.

Tool

Description

tableStats

Table and index sizes in bytes, estimated row count, dead tuples on PostgreSQL, last vacuum/analyze, and seq/idx scan counters. On Oracle, also includes best-effort DBA_SEGMENTS data when available

indexStats

Per-index size, scan counter, columns, unique/primary flag, and index type. PostgreSQL extras: idx_tup_read/fetch, pg_get_indexdef. Oracle extras: distinct_keys, clustering_factor, blevel, leaf_blocks, last_analyzed

unusedIndexes

Indexes with zero scans on PostgreSQL (pg_stat_user_indexes). PK and UNIQUE indexes are excluded. On Oracle, returns a diagnostic note because ALL_INDEXES does not expose usage counters; DBA_INDEX_USAGE 12.2+ or V$OBJECT_USAGE with ALTER INDEX ... MONITORING USAGE is needed

redundantIndexes

Indexes whose column list is a strict prefix of another index on the same table. Unique indexes are not reported because dropping them would remove a constraint. Index type must match

fkIndexCoverage

Foreign keys on the child side that lack a supporting index, a classic cause of slow DELETE / UPDATE CASCADE and slow JOINs. The result includes suggested_index_columns ready for CREATE INDEX

All tools are read-only; data is not modified.

Error Format

All tools return errors in the same shape: JSON with error and kind fields.

{"error": "Only SELECT / WITH / EXPLAIN statements are allowed", "kind": "rejected"}

kind

When

sql

The database returned a SQLException for syntax, missing object, missing permission, and similar cases

argument

Invalid tool argument

rejected

The read-only guard blocked the query before it reached the database

not_found

getViewDefinition, getRoutineDefinition, or getTriggerDefinition found nothing. The response body also includes missing and name

driver / unexpected / plan_parse

Internal driver failure, unhandled failure, or plan parsing failure

validateQuery uses its own shape, without kind; valid is the discriminator.

{"valid": true,  "parameters": 1, "columns": 3}
{"valid": false, "stage": "guard|params|driver", "error": "..."}

Read-only Protection

Protection is layered and is designed primarily for accidental DELETE / DROP statements from an LLM, not for a malicious actor. A malicious actor already has the database URL, username, and password — which is also why the server keeps credentials out of the environment, so that an agent does not casually acquire them.

  1. ReadOnlyGuard in project code. Before sending SQL to the database, the server first parses it with JSqlParser and checks the AST. Only a single SELECT, WITH, or EXPLAIN is allowed. Write CTEs, SELECT INTO, and locking clauses such as FOR UPDATE are forbidden. If JSqlParser cannot parse dialect-specific SQL, the guard falls back to the older lexical check: first meaningful token, multi-statement rejection, comment skipping, and write-keyword detection outside strings and quoted identifiers.

  2. connection.setReadOnly(true). Set by Hikari and again by this server on each checkout.

  3. PostgreSQL: default_transaction_read_only=on. Added to the JDBC URL automatically unless you already provided your own options=. Even server-side DDL is rejected.

  4. Oracle: JDBC read-only hint. Oracle JDBC treats setReadOnly(true) mostly as an advisory hint. The client-side guard and a dedicated read-only database user are the primary Oracle protections. Oracle EXPLAIN PLAN writes a static plan to PLAN_TABLE; this server scopes those reads with a generated STATEMENT_ID.

  5. SQL Server: JDBC read-only hint plus SHOWPLAN estimated plans. SQL Server also treats setReadOnly(true) as a hint. Use a least-privilege login/user for strong enforcement. explainQuery and analyzePlan use SHOWPLAN_TEXT/XML, which returns estimated plans without executing the statement.

Maximum Protection: Use a Read-only Database User

If you can spend five minutes, create a dedicated user with read-only permissions. This is the strongest guarantee even if the guard is accidentally disabled.

PostgreSQL:

CREATE ROLE ai_readonly LOGIN PASSWORD 'strong-password';
GRANT CONNECT ON DATABASE mydb TO ai_readonly;
GRANT USAGE ON SCHEMA public TO ai_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO ai_readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT SELECT ON TABLES TO ai_readonly;

Oracle:

CREATE USER ai_readonly IDENTIFIED BY "strong-password";
GRANT CREATE SESSION TO ai_readonly;
GRANT SELECT ANY DICTIONARY TO ai_readonly;  -- for metadata
-- For each required table/view:
GRANT SELECT ON app_schema.customers TO ai_readonly;
-- ...or a role collecting all SELECT grants:
-- CREATE ROLE ai_ro_role; GRANT ai_ro_role TO ai_readonly;

SQL Server:

CREATE LOGIN ai_readonly WITH PASSWORD = 'strong-password';
CREATE USER ai_readonly FOR LOGIN ai_readonly;
GRANT SELECT ON SCHEMA::dbo TO ai_readonly;
GRANT VIEW DEFINITION TO ai_readonly; -- for object definitions and richer metadata
GRANT SHOWPLAN TO ai_readonly;        -- for explainQuery/analyzePlan estimated plans

Disabling the Guard

If you need to call, for example, a stored procedure with read-only semantics that the guard does not allow, you can disable client-side validation:

"readonlyGuard": "off"

Connection-level protections (setReadOnly and, on PostgreSQL, default_transaction_read_only) remain enabled. On Oracle and SQL Server, setReadOnly is best-effort; use a read-only database user for the strongest guarantee.

Stack

  • Java 21, Spring Boot 4.0, Spring AI MCP 2.0.0-M6 (stdio transport)

  • HikariCP through Spring Boot starter-jdbc

  • PostgreSQL JDBC 42.7.4

  • Oracle JDBC ojdbc11 23.6.0.24.10

  • Microsoft SQL Server JDBC 12.8.1

  • SQLite 3.51.3 WAL catalog (<catalog>.db) holding the usage index and persistent structure snapshot

  • Gradle 9.3.1 with version catalog

License

This project is licensed under the Apache License, Version 2.0. See LICENSE.

Runtime and test dependencies are licensed by their respective owners. See THIRD_PARTY_NOTICES.md, especially if you distribute a built fat jar containing bundled JDBC drivers.

Build

# Set JDK 21+ explicitly if it is not your default JDK:
export JAVA_HOME="$HOME/.jdks/jdk-21.0.6"

./gradlew build

Result: build/libs/jdbc-mcp-server.jar (includes PostgreSQL, Oracle, and SQL Server drivers).

Integration Tests

Integration tests start real PostgreSQL, Oracle Free, and SQL Server instances through Testcontainers, so Docker is required. They are excluded from the regular build and run separately:

./gradlew integrationTest

To run only the SQL Server Testcontainers suite:

./gradlew integrationTest --tests "*SqlServerIntegration*"

The first Oracle Free and SQL Server runs download large images and may take several minutes to start.

Smoke Tests Against a Real Oracle Database

If you have access to an existing Oracle database, you can run read-only smoke tests (LiveOracleIntegrationTest) directly against it. The tests execute only SELECT queries against the dictionary (DUAL, ALL_TABLES) and the user schema; there are no CREATE / INSERT / UPDATE statements.

Username and password are not stored in the repository; they are passed through environment variables. If they are not set, the tests are skipped quietly and do not break the regular build.

export LIVE_ORACLE_URL='jdbc:oracle:thin:@db.example.com:1521:ORCL'
export LIVE_ORACLE_USERNAME='ai_readonly'
export LIVE_ORACLE_PASSWORD='secret'
# optional, defaults to LIVE_ORACLE_USERNAME uppercased:
# export LIVE_ORACLE_SCHEMA='APP_SCHEMA'

./gradlew liveOracleTest

Windows (PowerShell):

$env:LIVE_ORACLE_URL      = 'jdbc:oracle:thin:@db.example.com:1521:ORCL'
$env:LIVE_ORACLE_USERNAME = 'ai_readonly'
$env:LIVE_ORACLE_PASSWORD = 'secret'
./gradlew liveOracleTest

.env is listed in .gitignore; if desired, store variables there and load them before running tests, for example with direnv, dotenv-cli, or set -a; . ./.env; set +a in bash. Gradle does not parse .env itself; variables must already be present in the environment when Gradle starts.

Configuration

Databases, credentials and everything that varies per database live in connections.json — deliberately not in the environment. The environment configures only the server process itself:

Variable

Required

Description

JDBC_MCP_CONNECTIONS_FILE

no

Path of the JSON file describing the named connections this server serves; default <data-dir>/connections.json. A missing or empty file starts the server with no connections (warning logged); a malformed one is a startup error

JDBC_MCP_DATA_DIR

no

Root directory for server-local data, default ~/.jdbc-mcp-server. Each connection gets its own subdirectory under it

JDBC_MCP_RESOURCES_ENABLED

no

Expose the catalog-qualified manifest plus concrete table resources and table/column resource templates; default false

JDBC_MCP_TOOLS_*

no

Per-group tool toggles that control which tools appear in tools/list. All groups default to true; set a group to false to hide it (useful for small-context models). See Tool Groups

A connection's own settings — URL, credentials, default schema, timeouts, row caps, pool sizes, the read-only guard, snapshot and usage options — are fields of its connections.json entry; see Connection fields.

Running

With connections.json in place:

java -jar jdbc-mcp-server.jar

(Use build/libs/jdbc-mcp-server.jar if you built it locally, or the file downloaded from Releases.)

The server immediately starts listening for MCP over stdin/stdout. Logs are written to stderr. Tool calls address a database by the name it has in the file: "connection": "myapp".

Docker

The image is published to GHCR with every release. Mount the directory holding connections.json at /data — it is also where the server keeps its local catalogs and logs:

docker run -i --rm -v ~/.jdbc-mcp-server:/data ghcr.io/igorolv/jdbc-mcp-server:latest

The same command is what an MCP client should launch (-i keeps stdin open for the stdio transport). JDBC URLs in connections.json must be reachable from inside the container: use the database host name, not localhost, or add --network host on Linux. To build the image locally:

docker build -t jdbc-mcp-server .

Connecting an AI Client

Add this server to the client configuration:

{
  "command": "java",
  "args": ["-jar", "<absolute-path>/jdbc-mcp-server.jar"],
  "env": {}
}

There is nothing to put in env: the databases come from connections.json, and keeping credentials out of the client config is the point. Add JDBC_MCP_CONNECTIONS_FILE only if you keep the file somewhere other than the default path.

Where to Configure It

Client

Connection method

Claude Code

claude mcp add --scope user jdbc java -jar /path/to/jdbc-mcp-server.jar

Qwen Code

~/.qwen/settings.json -> "mcpServers" -> "jdbc"

VS Code

.vscode/mcp.json -> "servers" -> "jdbc"

Cursor

.cursor/mcp.json -> "mcpServers" -> "jdbc"

Claude Desktop

claude_desktop_config.json -> "mcpServers" -> "jdbc"

For Claude Code, omitting --scope user adds the server only to the current project. Check the connection with claude mcp list. Restart the client after adding the server.

Serving Several Databases from One Server

One server process can serve any number of named databases. The tool manifest stays a single set of 49 tools no matter how many are configured — each tool takes connection as its first argument — and a database's pool, local catalog and services are created the first time something actually asks for that connection.

This matters at scale: registering fifteen MCP server instances puts fifteen tool manifests into the agent's context and fifteen JVMs in memory, when the session may end up touching two of the databases.

Each database is one entry in connections.json; adding a database means adding an entry and restarting the server.

Choosing a connection

There is no default connection: every tool call names the database it means in its first argument. A missing or unknown name returns an argument error listing the available names. Call listConnections to see what exists — it reads configuration only, so it works even when some of the configured databases are down.

A single database

Nothing changes for one database: a connections.json with a single entry, and its name passed as connection. There is no environment-variable shortcut — one file is the whole configuration.

Isolation

  • Configuring a connection costs nothing until it is used: no pool, no catalog file, no connection.

  • Reaching database X opens pools for X only.

  • A database that is down, or an entry whose URL is not a supported JDBC URL, fails the calls made against it and leaves the other connections working. listConnections reports the reason in configError.

  • Each connection keeps its own local catalog at <data-dir>/<name>/<name>.db, so structure snapshots and usage indexes never mix.

  • MCP resources (when JDBC_MCP_RESOURCES_ENABLED=true) are published for every configured connection that already has a local catalog file; URIs were catalog-qualified already.

The single server process keeps its shared rolling log under <data-dir>/logs/jdbc-mcp-server.log. Log entries emitted while handling a tool call include its connection name; process-level entries use connection=server.

One instance per database (the earlier approach)

Registering one server instance per database still works and remains a reasonable choice for one or two databases. The client namespaces tools by server key, at the cost of one tool manifest and one JVM per database:

{
  "mcpServers": {
    "jdbc-orders": {
      "command": "java",
      "args": ["-jar", "<absolute-path>/jdbc-mcp-server.jar"],
      "env": {"JDBC_MCP_CONNECTIONS_FILE": "<absolute-path>/orders-connections.json"}
    },
    "jdbc-billing": {
      "command": "java",
      "args": ["-jar", "<absolute-path>/jdbc-mcp-server.jar"],
      "env": {"JDBC_MCP_CONNECTIONS_FILE": "<absolute-path>/billing-connections.json"}
    }
  }
}

Do not give two databases the same connection name, in either setup: their usage index and structure snapshot would share one <catalog>.db file.

Project Structure

+-- src/main/java/ru/it_spectrum/ai/jdbc/mcp/
|   +-- JdbcMcpServerApplication.java   - Spring Boot entry point
|   +-- config/
|   |   +-- JdbcProperties.java         - connection settings from env
|   |   +-- JdbcMcpProperties.java      - local data directory and catalog name
|   |   +-- UsageProperties.java        - usage-catalog sources and native-object settings
|   |   +-- StructureSnapshotProperties.java - schemas captured by rebuildCatalog
|   |   +-- DatabaseKind.java           - PG/Oracle/SQL Server autodetection from URL
|   |   +-- DataSourceConfig.java       - Hikari pool builder + connection-level read-only mode
|   |   +-- ConnectionsConfig.java      - global defaults and the connection registry bean
|   +-- connection/
|   |   +-- ConnectionsFile.java        - connections.json shape
|   |   +-- ConnectionsLoader.java      - file + env defaults -> connection definitions
|   |   +-- EnvironmentPlaceholders.java - ${ENV_VAR} substitution
|   |   +-- ConnectionDefinition.java   - one named database and its effective settings
|   |   +-- ConnectionRegistry.java     - configured connections, lazily built, closed on shutdown
|   |   +-- ConnectionContext.java      - the service graph of one connection
|   |   +-- SpringConnectionContextFactory.java - builds it as a lazy child ApplicationContext
|   |   +-- ConnectionScopeConfig.java  - per-connection DataSource and DatabaseKind beans
|   +-- dialect/
|   |   +-- SqlDialect.java             - dialect interface
|   |   +-- PostgresDialect.java        - EXPLAIN, pg_catalog, pg_get_viewdef
|   |   +-- OracleDialect.java          - EXPLAIN PLAN, ALL_VIEWS, ALL_SOURCE, Oracle metadata queries
|   |   +-- SqlServerDialect.java       - SHOWPLAN, sys catalog metadata, SQL Server pagination
|   |   +-- DialectConfig.java          - implementation selection by DatabaseKind
|   +-- sql/
|   |   +-- ReadOnlyGuard.java          - JSqlParser AST guard + lexical fallback
|   |   +-- SqlNotAllowedException.java
|   |   +-- QueryResult.java            - result shape
|   |   +-- SqlExecutor.java            - query execution with limits
|   |   +-- BenchmarkService.java       - benchmark (cold+warm) and timed (+ pg_stat_statements diff)
|   +-- metadata/
|   |   +-- MetadataService.java        - DatabaseMetaData + dialect-specific metadata
|   |   +-- SqliteStructureSnapshotStore.java - persistent SQLite structure snapshot
|   |   +-- StatsService.java           - table/index stats, FK coverage, redundant/unused indexes
|   |   +-- DistributionService.java    - column distribution / histogram / null ratio / selectivity / join cardinality
|   |   +-- SchemaContextService.java   - high-level schema context: overview, table context, join paths, graph, lint, brief, query context
|   +-- plan/
|   |   +-- ParsedPlan.java / PlanNode.java - unified engine-agnostic plan model
|   |   +-- PlanParser.java             - parser interface
|   |   +-- PostgresPlanParser.java     - JSON EXPLAIN -> tree
|   |   +-- OraclePlanParser.java       - PLAN_TABLE -> tree
|   |   +-- SqlServerPlanParser.java    - SHOWPLAN_XML -> tree
|   |   +-- PlanAnalyzer.java           - summary: expensive / full scan / estimate error / nested loop / spill
|   +-- usage/
|   |   +-- CatalogDataSourceConfig.java - SQLite WAL datasource + schema init
|   |   +-- CatalogStorageService.java  - WAL checkpoint for distributable catalogs
|   |   +-- UsageCatalogService.java    - ingest, lookups, observed-relationships aggregation
|   |   +-- format/
|   |   |   +-- QueryUsage.java         - canonical query usage record DTO
|   +-- tools/
|       +-- QueryTools.java             - executeQuery, explainQuery, analyzePlan, validateQuery, inspectQuery, queryLint, resolveQueryLineage
|       +-- MetadataTools.java          - schemas / tables / describe / view / routines / sequences / search
|       +-- AdminTools.java             - rebuildCatalog (build structure snapshot + usage index into a distributable <catalog>.db)
|       +-- SampleTools.java            - sampleRows
|       +-- DistributionTools.java      - columnStats, columnDistribution, columnHistogram, nullRatio, estimateSelectivity, joinCardinality
|       +-- StatsTools.java             - tableStats, indexStats, unusedIndexes, redundantIndexes, fkIndexCoverage
|       +-- BenchmarkTools.java         - benchmarkQuery, timedQuery
|       +-- SchemaContextTools.java     - schemaBrief, tableContext, findJoinPaths, schemaLint, schemaGraph, queryContext, schemaGraphDot
|       +-- UsageTools.java             - usageCatalogStatus, invalidateUsageCatalogCache, getQuery, listQueries, findQueriesBy(Table|Column), observedRelationships, listKnownTags/Domains/Kinds
+-- src/main/resources/
    +-- application.yml                 - MCP stdio + JDBC properties
    +-- usage-catalog-schema.sql        - DDL for the usage-catalog index (in <catalog>.db)
    +-- structure-snapshot-schema.sql   - DDL for the persistent structure snapshot (in <catalog>.db)
    +-- logback-spring.xml              - logs to stderr because stdout is used by MCP

Troubleshooting

  • "Cannot find a Java installation ... matching languageVersion=21" - install JDK 21+ and set JAVA_HOME. Gradle toolchains cannot download it without internet access.

  • Connection refused / ORA-01017 / FATAL / SQL Server login failed - check the connection's url, username, and password in connections.json. For PostgreSQL, test the URL with psql; for Oracle, use sqlplus user/password@...; for SQL Server, test with sqlcmd -S host,1433 -d database -U user -P password.

  • {"kind":"rejected","error":"Only SELECT / WITH / EXPLAIN statements are allowed"} - the guard worked. This is expected for any write operation. If the query is truly read-only, for example a read-only function call through SELECT func(...), it will pass. For fully non-trivial cases, you can disable the guard with "readonlyGuard": "off" on that connection.

  • Oracle write attempt reached the database - this should normally be blocked by the guard first. If readonlyGuard is off, rely on a read-only Oracle user; JDBC setReadOnly(true) is only a best-effort hint for Oracle.

  • Empty describeTable / listTables result on Oracle - Oracle stores object names in uppercase. Pass CUSTOMERS, not customers.

  • SQL Server certificate errors - set the JDBC URL encryption options explicitly, for example encrypt=true;trustServerCertificate=false with a trusted certificate, or trustServerCertificate=true only for local/dev use.

  • SQL Server unusedIndexes unsupported - this tool intentionally avoids sys.dm_db_index_usage_stats because it usually requires elevated state-view permissions. Use indexStats, fkIndexCoverage, and redundantIndexes for low-privilege SQL Server audits.

Available Tools

49 tools
analyzePlananalyzePlanA
Read-onlyIdempotent

Diagnose query-plan performance with compact structured findings: expensive nodes, large-table full scans, estimation errors, risky nested loops and disk-sort spills. Use explainQuery when the full textual plan is required. Bind '?'->params, ':name'->namedParams; never mix. E.g. :status -> namedParams={status:'PAID'} — key is the bare name.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes
paramsNoValues for '?' placeholders, in order.
analyzeNoExecute the query to collect runtime stats where supported (default false).
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
namedParamsNoValues for ':name' placeholders, keyed by name.

Output Schema

ParametersJSON Schema
NameRequiredDescription
rootNoRoot node of the execution plan.
engineNoDatabase engine that produced the result, such as PostgreSQL, Oracle, or SQL Server.
analyzedYesTrue when the plan includes actual execution metrics, not only estimates.
fullScansNoPlan nodes that perform full table or index scans and may deserve attention.
nodeCountYesNumber of table nodes in the schema graph.
diskSpillsNoSort or hash nodes that appear to spill to disk.
planningTimeMsNoPlanner time reported by the database, in milliseconds when available.
executionTimeMsNoExecution time reported by the database, in milliseconds when available.
estimationErrorsNoPlan nodes where actual rows differ materially from estimated rows.
riskyNestedLoopsNoNested-loop nodes that may be expensive because the outer side is large.
topExpensiveNodesNoPlan nodes ranked as most expensive by cost or actual time.

TDQS

A4.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as read-only, idempotent, and non-destructive. The description adds value by disclosing that output is 'compact structured findings' rather than a full textual plan and enumerates the diagnostic categories. It does not contradict annotations, though it doesn't discuss the runtime-execution implications of the analyze parameter, which is covered in the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: first the purpose, then the alternative tool, then the binding rule with a concrete example. Every sentence earns its place with no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, detailed return structure is unnecessary. The description covers the key routing decision, the parameter binding convention, and the diagnostic scope, while remaining fields like connection and analyze are already documented in the schema. This is complete for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already high, but the description adds critical binding semantics beyond the schema: '?' maps to params, ':name' maps to namedParams, never mix, and the example clarifies that the object key should be the bare name without the colon. This directly helps an agent construct valid calls.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the tool diagnoses query-plan performance and lists concrete findings it returns: expensive nodes, large-table full scans, estimation errors, risky nested loops, and disk-sort spills. It uses a specific verb ('Diagnose') with a clear resource ('query-plan performance') and differentiates itself from explainQuery in the next sentence.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit selection guidance: 'Use explainQuery when the full textual plan is required.' This directly tells the agent when not to use analyzePlan and which sibling tool is appropriate instead. It also includes binding instructions that guide correct invocation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

benchmarkQuerybenchmarkQueryA
Read-onlyIdempotent

Measure repeatable query latency with separate cold runs and min/median/max warm-run timings. Use for comparing query rewrites, not retrieving data; timedQuery is the one-run alternative that returns rows. Bind '?'->params, ':name'->namedParams; never mix. E.g. :status -> namedParams={status:'PAID'} — key is the bare name. Returns the size of the last result (rows, columns, truncated), not the rows.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes
limitYesRow limit per run (> 0).
paramsNoValues for '?' placeholders, in order.
coldRunsNoCold runs (default 1); executed first.
warmRunsNoWarm runs (default 3).
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
namedParamsNoValues for ':name' placeholders, keyed by name.
timeoutSecondsYesTimeout per run in seconds (> 0).

Output Schema

ParametersJSON Schema
NameRequiredDescription
noteNoAdditional context about support, limits, interpretation, or engine-specific behavior.
runsYesNumber of measured runs included in these timing statistics.
allMsNoIndividual elapsed times for all benchmark executions, in milliseconds.
limitYesRow limit applied to the query or page size requested by the caller.
coldMsNoTiming statistics for cold benchmark runs in milliseconds.
engineNoDatabase engine that produced the result, such as PostgreSQL, Oracle, or SQL Server.
warmMsNoTiming statistics for warm benchmark runs in milliseconds.
coldRunsYesNumber of cold runs executed before warm measurements.
warmRunsYesNumber of warm runs used for the primary benchmark statistics.
resultSizeNo
timeoutSecondsYesPer-statement timeout applied during execution, in seconds.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/idempotent/destructive annotations, the description discloses key behavior: it returns only the size of the last result (rows, columns, truncated) rather than the rows themselves. It also explains the binding model ('?' vs ':name') and warns against mixing them. These are meaningful behavioral details not visible in the annotations alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences deliver purpose, usage guidance, binding rules, and return behavior without filler. Information is front-loaded: the core purpose appears first, then usage alternatives, then parameter and return semantics. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 8-parameter tool with an output schema, the description covers the critical invocation context: when to use it, how to bind parameters, what it returns, and why it differs from timedQuery. Remaining details like default run counts, timeout, and valid connection names are already present in the parameter schema, so nothing necessary for correct use is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents 88% of parameters, including descriptions for 'params' and 'namedParams', so the baseline is 3. The description adds a concrete example (':status -> namedParams={status:'PAID'}'), clarifies that the key is the bare name, and warns never to mix binding styles. This adds value but is not essential given the schema's coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Measure') on a specific resource ('repeatable query latency') and defines the output as cold runs plus min/median/max warm-run timings. It also distinguishes itself from the sibling timedQuery by noting that timedQuery is the one-run alternative that returns rows. This makes the tool's purpose unambiguous and separable from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says 'Use for comparing query rewrites, not retrieving data' and names timedQuery as the alternative that returns rows. This gives the agent both a positive and negative usage condition, which is strong guidance for tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

columnDistributioncolumnDistributionA
Read-onlyIdempotent

Measure value frequency and skew for one known column by returning top-N values, counts and row shares. Use columnStats for only cardinality/extremes; runs GROUP BY + COUNT and may be expensive on large tables.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNNoTop values to return (default 20, max 1000).
tableYes
columnYes
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
topNYesMaximum number of most-frequent values requested for the distribution.
tableNo
columnNoColumn whose value frequencies were measured.
schemaNo
valuesNoMost frequent values and their frequencies for the column.
topRowsYesRows covered by the returned top-N value buckets.
topRatioYesShare of all rows covered by the returned top-N buckets, from 0.0 to 1.0.
otherRowsYesRows not represented by the returned top-N value buckets.
totalRowsYesTotal number of rows considered for this statistic.
otherRatioYesShare of all rows outside the returned top-N buckets, from 0.0 to 1.0.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is known. The description adds value beyond annotations by disclosing that execution performs GROUP BY + COUNT and may be expensive on large tables. This is useful behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no fluff. It front-loads the core purpose, immediately gives the sibling distinction, and ends with a concise performance warning. Every sentence contributes useful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists, the description does not need to explain return values. It covers purpose, usage distinction, and cost. The only minor gap is that it doesn't mention that schema is optional, but required parameters and the connection hint largely compensate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds some meaning beyond the schema by clarifying that column must be a single known column and by referencing top-N values, which maps to the topN parameter. However, with only 40% schema description coverage, the description does not fully compensate for the lack of documentation on schema and table parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Measure') with a clear resource ('value frequency and skew for one known column') and states the output shape ('top-N values, counts and row shares'). It also distinguishes itself from a sibling tool, columnStats, by naming what that tool is for.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use columnStats instead ('for only cardinality/extremes'), which implies when to use this tool (i.e., when distribution and skew are needed). It also warns that the tool runs GROUP BY + COUNT and may be expensive, giving practical usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

columnHistogramcolumnHistogramA
Read-onlyIdempotent

Measure percentile distribution for one orderable numeric, date, timestamp or text column: min/max, P25/P50/P75/P90/P95/P99 and null counts. Use columnDistribution for top frequent values instead.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableYes
columnYes
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
maxNoMaximum observed non-null column value.
minNoMinimum observed non-null column value.
p25No25th percentile value for the column.
p50NoMedian, or 50th percentile, value for the column.
p75No75th percentile value for the column.
p90No90th percentile value for the column.
p95No95th percentile value for the column.
p99No99th percentile value for the column.
tableNo
columnNoColumn whose percentile distribution was measured.
schemaNo
nullRowsYesNumber of rows where the column value is NULL.
nullRatioYesShare of rows where the column value is NULL, from 0.0 to 1.0.
totalRowsYesTotal number of rows considered for this statistic.
columnTypeNoDatabase type of the column used to choose percentile behavior.
nonNullRowsYesNumber of rows where the column value is not NULL.
percentileFunctionNoDatabase percentile function used, such as continuous or discrete percentile.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, so the safety profile is covered. The description adds meaningful behavioral context beyond annotations: the accepted column types (numeric, date, timestamp, text), the requirement that the column be orderable, and the precise set of statistics returned including null counts.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler: the first front-loads the purpose and exact output statistics, and the second gives a clear alternative. Every word contributes to selecting or invoking the tool correctly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the presence of a full output schema, the description does not need to explain return values. Combined with annotations for read-only behavior and the explicit sibling routing, it covers the essential information an agent needs. A minor gap is the lack of guidance on how to specify tables/schemas, but the schema's standard parameter names make this largely self-evident.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25%; the connection parameter is well-documented in the schema itself. The description partially compensates for the undocumented column parameter by specifying that it must be an orderable numeric, date, timestamp, or text column. However, the table and schema parameters receive no added meaning, and the description does not clarify how to qualify the table or handle the optional schema parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Measure') and resource ('percentile distribution for one orderable numeric, date, timestamp or text column') and enumerates exact outputs (min/max, P25/P50/P75/P90/P95/P99, null counts). It also distinguishes itself from columnDistribution by explicitly naming that sibling as the alternative for top frequent values.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for when to use this tool: when percentile distribution for a single orderable column is needed. It explicitly instructs to use columnDistribution for top frequent values instead, providing a direct exclusion and routing the agent to a sibling tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

columnStatscolumnStatsA
Read-onlyIdempotent

Measure basic extremes and cardinality for one known column: total/non-null rows, distinct count and min/max. Use columnDistribution for frequent values or columnHistogram for percentiles.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableYes
columnYes
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
tableNo
columnNoColumn whose basic statistics were measured.
schemaNo
maxValueNoMaximum observed non-null value for the column.
minValueNoMinimum observed non-null value for the column.
totalRowsYesTotal number of rows considered for this statistic.
nonNullRowsYesNumber of rows where the column value is not NULL.
distinctValuesYesEstimated or exact number of distinct non-null values.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark it read-only and idempotent, and the description adds behavioral scope: it operates on a single known column rather than scanning all columns, and it specifies exactly which statistics are computed. It does not mention return shape, but an output schema exists and the annotations cover safety.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two clauses in a single sentence: the first states purpose and outputs, the second gives routing to siblings. Every word earns its place, with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only statistics tool with an output schema, the description covers what it computes and how it differs from related tools. Remaining gaps, such as how schema is selected or null handling, are minor given the output schema and annotation set.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25% (only connection is described). The description clarifies that the column parameter targets one known column, but it does not explain table/schema semantics, the optionality of schema, or naming conventions. This insufficiently compensates for the low coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses 'Measure' as a specific verb, identifies the resource as 'one known column', and enumerates the exact outputs (total/non-null rows, distinct count, min/max). It also names sibling tools columnDistribution and columnHistogram, distinguishing this from them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use this tool – for basic extremes and cardinality on one column – and when to use alternatives: columnDistribution for frequent values, columnHistogram for percentiles. The connection parameter guidance in the schema also directs the agent to listConnections for valid names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

describeTabledescribeTableA
Read-onlyIdempotent

Inspect one known table or view. Use for its fields/columns, types, nullability, defaults, comments, keys, indexes, constraints or triggers. Returns full metadata for that object only; use tableContext when nearby relationships or joins are also needed.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableYes
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
nameNo
typeNoDescribed object type, such as TABLE, VIEW, or MATERIALIZED VIEW.
schemaNo
columnsNoColumn list in database order; for keys, indexes, and joins the order is significant.
indexesNoIndexes available on the table or returned by an index-statistics scan.
remarksNoDatabase comment or description attached to the object, when the driver exposes it.
triggersNoTriggers attached to the table, usually without full body unless requested (opaque).
primaryKeyNo
foreignKeysNoOutgoing foreign keys declared by the table.
referencedByNoIncoming foreign keys from other tables that reference this table (opaque).
checkConstraintsNoCHECK constraints declared on the table, with raw expression and parsed allowed values when available.
uniqueConstraintsNoUnique constraints declared on the table.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior Mend, so the description mainly adds scope context. It discloses that it works on one known object, returns metadata for that object only, and that full metadata is the output. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with strong front-loading: the first states the primary action and benefits, the second clarifies scope and the sibling alternative. Every phrase earns its place and there is no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a metadata inspection tool with rich annotations and an output schema, the description is largely complete. It provides scope, alternative routing, and behavior. The only meaningful gap is the undocumented 'schema' parameter, which prevents a perfect score.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%: only 'connection' is described in the schema. The tool description does not compensate by explaining what 'table' and 'schema' mean, whether schema is optional, or how the table identifier should be qualified. This leaves a gap for an agent selecting parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Inspect one known table or view.' It clarifies the scope and lists concrete metadata facets (fields, columns, types, nullability, defaults, comments, keys, indexes, constraints, triggers), making it distinct from sibling tools like tableContext.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states when to use this tool ('Inspect one known table or view') and explicitly names the alternative for related needs: 'use tableContext when nearby relationships or joins are also needed.' This gives clear routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

estimateSelectivityestimateSelectivityA
Read-onlyIdempotent

Estimate how selective one proposed table predicate is without executing the query. Returns planner-estimated rows, the unfiltered baseline and their ratio; use when evaluating filters or composite-index column order.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableYes
schemaNo
predicateYesRaw boolean SQL without WHERE or ';'.
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
noteNoAdditional context about support, limits, interpretation, or engine-specific behavior.
tableNoTable on which the predicate selectivity was estimated.
schemaNo
predicateNoRaw SQL predicate without the WHERE keyword used for selectivity estimation.
selectivityNoEstimated predicate selectivity, calculated as estimated rows divided by baseline rows.
baselineRowsNoPlanner row estimate for the table without the predicate.
estimatedRowsNoPlanner or catalog estimate of rows for this object or operation.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds the important behavior that no query is executed and that results are planner estimates rather than actual row counts. It also discloses the output shape (rows, baseline, ratio) beyond what the input schema provides, though it does not address error behavior or limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly packed sentences lead with the core action, then state the return values and usage context without repetition or filler. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only estimation tool with idempotence annotations and an output schema present, the description provides the essential behavioral distinction (no execution), the output semantics, and the two primary use cases. Nothing critical is missing for an agent to decide whether and how to call it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With schema description coverage at 50%, the schema already documents predicate and connection. The description clarifies that the predicate is a proposed table filter and that the baseline is the unfiltered count, but table and schema parameters remain mostly implicit and are not described in the text, so the description only partially compensates for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening verb 'Estimate' plus the object 'selectivity of one proposed table predicate' states exactly what the tool computes, and 'without executing the query' sets it apart from execution-oriented siblings such as executeQuery and timedQuery. The return values and intended use cases further clarify the resource being analyzed.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Use when evaluating filters or composite-index column order' gives explicit context for choosing this tool. It does not name alternatives or explicit when-not-to-use conditions, but the 'proposed... without executing' wording makes the boundary versus query execution clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

executeQueryexecuteQueryA
Read-onlyIdempotent

Run a read-only SQL SELECT / WITH / EXPLAIN when actual result rows are needed. Use timedQuery for one timed execution or benchmarkQuery for repeated latency measurements. Bind '?'->params, ':name'->namedParams; never mix. E.g. :status -> namedParams={status:'PAID'} — key is the bare name. Sets 'truncated' when the row cap is hit.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes
limitNoRow limit (default JDBC_MAX_ROWS).
paramsNoValues for '?' placeholders, in order.
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
namedParamsNoValues for ':name' placeholders, keyed by name.
timeoutSecondsNoTimeout in seconds (default JDBC_QUERY_TIMEOUT_SECONDS).

Output Schema

ParametersJSON Schema
NameRequiredDescription
rowsNoRows.
columnsNoColumns.
rowCountYesRow Count.
truncatedYesTruncated.
columnTypesNoColumn Types.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only and non-destructive behavior, and the description adds meaningful behavioral context: 'Sets truncated when the row cap is hit.' The binding rule 'never mix' also discloses a constraint not present in the annotations. No contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three dense sentences cover purpose, alternatives, binding semantics, example, and truncation behavior. The most important usage guidance is front-loaded, and every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is complete for an agent invoking the tool: it states the query types allowed, the sibling tools for timing, parameter binding rules, and the truncation signal. The output schema and annotations cover return values and safety, so nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 83%, but the description adds real value by explaining the relationship between '?' placeholders and params, ':name' placeholders and namedParams, and gives a concrete example with the bare-name rule. This goes beyond the schema's short descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Run a read-only SQL SELECT / WITH / EXPLAIN when actual result rows are needed.' It also distinguishes the tool from timedQuery and benchmarkQuery, making it clear this is the general row-returning query tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says 'Use timedQuery for one timed execution or benchmarkQuery for repeated latency measurements,' giving an agent concrete alternative-selection criteria. The phrase 'when actual result rows are needed' further clarifies the intended use case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

explainQueryexplainQueryA
Read-onlyIdempotent

Return the full engine-specific textual execution plan for a SELECT / WITH statement. Use when raw plan detail is needed; prefer analyzePlan for compact performance findings. Bind '?'->params, ':name'->namedParams; never mix. E.g. :status -> namedParams={status:'PAID'} — key is the bare name.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes
paramsNoValues for '?' placeholders, in order.
analyzeNoExecute the query to collect runtime stats where supported (default false).
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
namedParamsNoValues for ':name' placeholders, keyed by name.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, covering the safety profile. The description adds useful behavioral context beyond that: the return is a full engine-specific textual plan, and parameter binding follows strict '?' vs ':name' conventions that must not be mixed. This is meaningful operational transparency for an agent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences with no filler. It front-loads the core purpose, then gives usage guidance, then explains parameter binding with an example. Every sentence contributes essential information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having no output schema, the description tells the agent the return kind ('textual execution plan') and the tool's scope. Combined with the schema's parameter descriptions and the annotations' safety profile, the agent has enough information to select and invoke the tool correctly. The explicit binding rule and sibling alternative complete the picture.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 80%, so the schema already documents most parameters. The description adds value by clarifying the binding model: '?' maps to params, ':name' maps to namedParams, and the example shows that the key is the bare name without the colon. This goes beyond the schema descriptions and reduces ambiguity.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Return the full engine-specific textual execution plan for a SELECT / WITH statement.' It also distinguishes itself from analyzePlan by contrasting raw plan detail with compact performance findings, making sibling differentiation clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states when to use the tool ('Use when raw plan detail is needed') and names the preferred alternative for compact performance findings ('prefer analyzePlan'). This gives an agent concrete routing guidance rather than leaving the choice implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

findJoinPathsfindJoinPathsA
Read-onlyIdempotent

Find join paths when both endpoint tables are known but the intermediate relationships are not. Traverses declared FK and optional observed join edges in both directions; for one table's immediate neighborhood, use tableContext.

ParametersJSON Schema
NameRequiredDescriptionDefault
toTableYes
maxDepthNoMaximum FK hops. Default 4.
maxPathsNoMaximum paths to return. Default 5, max 25.
toSchemaNo
fromTableYes
scanLimitNoMaximum tables to scan (default 300).
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
fromSchemaNo
includeObservedNoInclude usage-catalog equi-joins (default: catalog enabled).

Output Schema

ParametersJSON Schema
NameRequiredDescription
pathsNoJoin paths from the source table to the target table; each path is an ordered list of steps.
toTableNo
maxDepthYesMaximum relationship traversal depth that was applied.
toSchemaNo
fromTableNo
pathCountYesNumber of join paths returned after caps were applied.
fromSchemaNo
includeObservedYesTrue when usage-catalog observed joins were included as relationship evidence.
schemaTablesScannedYesNumber of schema tables inspected while searching the relationship graph.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds meaningful behavioral detail beyond annotations: it traverses 'declared FK and optional observed join edges in both directions,' which clarifies the search mechanics and the includeObserved parameter intent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The purpose is front-loaded, the traversal behavior is summarized, and the sibling routing is delivered in a compact closing clause.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has a rich output schema and annotations covering read-only, idempotent, and non-destructive behavior, the description provides the needed selection and invocation context without forcing the agent to infer usage. It explains when to use it, what it traverses, and how it differs from a key sibling.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 56%, so several parameters (fromTable, toTable, fromSchema, toSchema) lack schema-level descriptions. The description compensates by framing these as 'endpoint tables' and clarifying the task involves unknown 'intermediate relationships,' which directly informs how to set fromTable and toTable. It does not elaborate schema parameters, but the core ambiguity is addressed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific action and resource: 'Find join paths when both endpoint tables are known but the intermediate relationships are not.' It clearly distinguishes the tool from tableContext by stating that the immediate neighborhood case belongs to that sibling, so an agent can tell them apart without inspecting schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the precise condition to use the tool ('when both endpoint tables are known but the intermediate relationships are not') and explicitly points to the alternative ('for one table's immediate neighborhood, use tableContext'). This gives actionable selection guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

findQueriesByColumnfindQueriesByColumnA
Read-onlyIdempotent

Find stored application/report queries that actually reference one column and show whether it appears in SELECT, WHERE, JOIN, ORDER BY or HAVING. Use describeTable to discover declared columns; schema/table filters are optional and case-insensitive.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableNo
columnYes
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNumber of matching catalog queries returned for the column.
tableNoTable containing the searched column.
columnNo
schemaNo
matchesNoUsage-catalog matches returned for the requested table, column, or filter.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only, idempotent, non-destructive behavior. The description adds meaningful details beyond that: it searches stored queries rather than live data, checks specific SQL clauses, and emphasizes that column references are 'actual' rather than merely declared. This aligns with annotations and enriches the agent's expectations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loads the core behavior in the first sentence, and uses the second sentence for actionable guidance. Every phrase earns its place with no repetition of schema or annotation details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the presence of an output schema, return-value details are not required. The description covers scope, filtering behavior, and a discovery workflow. It is slightly incomplete in not explicitly steering the agent away from sibling tools like findQueriesByTable, but the core calling context is sufficiently covered.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25%, so the description must compensate. It clarifies that 'column' is the search target and that schema/table act as optional, case-insensitive filters. The connection parameter is already documented in the schema, but the description could still say more about how table/schema values are matched.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: find stored application/report queries that reference one column and show where the column appears (SELECT, WHERE, JOIN, ORDER BY, HAVING). This specific verb+resource combination distinguishes it from sibling tools like findQueriesByTable and searchObjects.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives useful context: use describeTable to discover declared columns, and schema/table filters are optional and case-insensitive. It does not explicitly name alternatives or exclusions, but the workflow and filter behavior are clear enough for an agent to call it appropriately.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

findQueriesByTablefindQueriesByTableA
Read-onlyIdempotent

Find stored application/report queries that actually reference one known table. Use to learn observed filters, joins and business usage, not to inspect declared table structure; resolved names are matched case-insensitively.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableYes
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNumber of matching catalog queries returned for the table.
tableNoTable searched in the usage catalog.
schemaNo
matchesNoUsage-catalog matches returned for the requested table, column, or filter.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as read-only and non-destructive. The description adds meaningful behavioral details beyond that: results are based on 'actually reference[d]' tables, names are matched case-insensitively, and the focus is on observed query usage rather than declared schema. This gives the agent useful runtime expectations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two focused sentences deliver the core purpose, usage guidance, and a key matching rule without redundancy. The main action is front-loaded alerting an agent immediately what the tool is for.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists and annotations cover safety, the description is largely complete for invoking the tool correctly. It covers purpose, usage boundary, matching behavior, and required input intent. The only minor gap is not naming a sibling alternative for declared table structure, but this is not essential to making a correct call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%, so the description must carry parameter meaning. It partially does by explaining that the tool resolves a 'known table' and matches names case-insensitively, but it does not clarify the optional 'schema' parameter or how it constrains the search. The connection parameter is already documented in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Find stored application/report queries that actually reference one known table.' It also clarifies the intended purpose ('observe filters, joins and business usage') and explicitly contrasts with table structure inspection, making it easy to distinguish from schema-focused siblings like describeTable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states when to use the tool: to learn observed filters, joins, and business usage. It also gives a when-not: 'not to inspect declared table structure.' However, it does not explicitly name the alternative tool for inspecting structure, so it falls just short of fully explicit routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fkIndexCoveragefkIndexCoverageA
Read-onlyIdempotent

Audit child-side foreign keys for missing supporting indexes. Returns only FKs not covered by an index starting with the FK columns in order, plus suggested index columns; use describeTable to inspect all keys and indexes of one table.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableNoOmit to scan the schema.
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
tableNo
schemaNo
uncoveredNoForeign keys that lack a supporting child-side index.
tablesScannedYesNumber of tables inspected by the tool before caps were applied.
uncoveredCountYesNumber of foreign keys without a supporting child-side index.
foreignKeysTotalYesTotal number of foreign keys inspected for index coverage.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as read-only, idempotent, and non-destructive. The description adds the specific output behavior (only returns uncovF FKs, includes suggested index columns), which is useful beyond annotations. It does not mention edge cases or side effects, but for a read-only audit tool this is adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with the core purpose first and the alternative second. No redundant wording, every sentence contributes meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value details are covered. The description explains behavior, output filtering, and an alternative tool. The only notable gap is the undocumented schema parameter, which prevents a perfect score.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 67%, with table and connection documented in the schema but the schema parameter is undocumented. The tool description adds no additional parameter semantics beyond the schema, leaving the schema parameter ambiguous. A score of 3 reflects the adequate but not complete parameter guidance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific audit task (child-side foreign keys), the precise filter (FKs not covered by an index starting with FK columns in order), and the output (suggested index columns). It also distinguishes itself from describeTable by noting what describeTable is for, making its purpose unambiguous relative to at least one sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit alternative ('use describeTable to inspect all keys and indexes of one table') and a usage condition for the table parameter ('Omit to scan the schema'). It does not enumerate when-not conditions for other sibling tools like redundantIndexes, but the context for when to use this tool is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getQuerygetQueryA
Read-onlyIdempotent

Retrieve the complete stored record for one query whose source identity is already known. Returns SQL, parameters, parsed tables/columns/joins, outputs and field usages; use listQueries, findQueriesByTable or findQueriesByColumn to discover matching records first.

ParametersJSON Schema
NameRequiredDescriptionDefault
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
sourceKindYesSource kind, e.g. dao, report, database-view.
sourcePathYesStable source path, e.g. file path.
sourceUnitNoOptional sub-unit, e.g. method name.

Output Schema

ParametersJSON Schema
NameRequiredDescription
tagsNoBusiness tags attached to the usage-catalog query.
rawSqlNoOriginal SQL text stored in the usage catalog.
tablesNoTables included in this context, graph, query inspection, or usage record.
columnsNoResolved column references extracted from the known query.
outputsNoDocumented output fields produced by the query.
joinPairsNoJoin pairs extracted from the query and stored in the usage catalog.
parametersNoDocumented parameters for this known query.
sourceKindNoKind of source that produced the catalog query, such as file, view, routine, or configured import.
sourcePathNoPath or database object name where the catalog query came from.
sourceUnitNoStable unit identifier inside the source, such as query id, method name, view name, or routine name.
fieldUsagesNoSemantic field usages attached to the query outputs or expressions.
parseStatusNoSQL parse status for a catalog query, such as parsed or failed.
businessLabelNo
normalizedSqlNoNormalized SQL text produced by parser or usage-catalog indexing.
businessDomainNoBusiness domain assigned to the catalog query or usage record.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds value by specifying exactly what the returned record contains (SQL, parameters, parsed components, outputs, field usages), which is behavioral detail beyond the annotations. It does not contradict annotations and does not discuss edge cases like pagination, but that is minor for a read-only retrieval tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero waste: the first states purpose and return content, the second gives routing to sibling tools. The most important info is front-loaded, and every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only retrieval tool with a full output schema and complete parameter documentation, the description is complete. It covers purpose, what is returned, and how to discover the required identity. The existence of an output schema means return-value details need not be repeated, and annotations cover safety. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with each parameter (connection, sourceKind, sourcePath, sourceUnit) having a description. The description adds the concept of 'source identity' and that these parameters identify the query, but it does not add syntax or format details beyond what the schema already provides. Since the schema carries the heavy lifting, the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Retrieve') with a clear resource ('the complete stored record for one query') and explicitly enumerates the returned content (SQL, parameters, parsed tables/columns/joins, outputs, field usages). It also names sibling tools (listQueries, findQueriesByTable, findQueriesByColumn) as the discovery path, distinguishing this retrieval tool from search tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells the agent when to use this tool: when the source identity is already known, and instructs to use listQueries, findQueriesByTable, or findQueriesByColumn to discover matching records first. This provides clear context and exclusions, leaving no ambiguity about when to select this tool over its siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getRoutineDefinitiongetRoutineDefinitionA
Read-onlyIdempotent

Return the source code of one known function, procedure or package, including its body where available. Use listRoutines to discover routine names.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds one useful behavioral nuance: the body is included 'where available', implying some routines may have no body. It does not contradict annotations, though it does not discuss error behavior or permissions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler: the primary behavior is front-loaded and the discovery pointer is a single clear clause. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the core return value (source code, body where available) and directs agents to listRoutines for discovery, while annotations cover the safety profile. The main gap is the undocumented optional schema parameter and absence of not-found/error behavior, but for a simple read-only getter this is nearly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%, with only connection documented. The description adds meaning for name by calling it a known routine and pointing to listRoutines, but the optional schema parameter is never explained and name lacks format details. With low schema coverage, the description only partially compensates.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Return the source code') on a defined resource ('one known function, procedure or package') and clarifies scope with 'including its body where available.' It also points to listRoutines for discovery, which helps differentiate it from search-oriented siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly tells agents to use listRoutines to discover routine names, which provides clear context for when to use that sibling first. It does not spell out exclusions like triggers/views, but the 'known' routine requirement implies this tool is for direct retrieval, not discovery.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getTriggerDefinitiongetTriggerDefinitionA
Read-onlyIdempotent

Return the full definition/body of one known table trigger. For trigger names and compact metadata, use describeTable first.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableYes
schemaNo
triggerYes
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already convey read-only, idempotent, and non-destructive behavior. The description adds a small amount of context: it returns the 'full definition/body' and requires a 'known' trigger. It does not contradict annotations, nor does it provide extra detail on errors or missing-trigger behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The primary purpose is front-loaded, and the routing guidance is placed second. Every clause adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only lookup by identifier, the description is sufficient: it tells the agent what to retrieve and directs it to find identifiers when absent. Gaps are minor: it does not explicitly describe return format, missing-trigger behavior, or whether schema is optional, but the simple nature of the tool and the annotations reduce the burden.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25% (connection only). The description partially compensates by saying 'one known table trigger' and routing to describeTable for trigger names, which implies what table and trigger mean. However, it leaves schema semantics, the optional nature of schema, and trigger/table formatting details to be inferred.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb-resource pair: 'Return the full definition/body of one known table trigger.' It is clearly distinct from the metadata-focused describeTable, and the phrase 'table trigger' differentiates it from sibling tools like getRoutineDefinition or getViewDefinition.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence gives an explicit precondition: use describeTable first when you need trigger names or compact metadata. It makes clear the tool expects a known, specific trigger, which is exactly the guidance an agent needs to decide between this tool and its sibling metadata tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getViewDefinitiongetViewDefinitionA
Read-onlyIdempotent

Return the SQL text that defines one known view or materialized view. For its exposed fields, keys and other object metadata, use describeTable.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds the 'known view' constraint and the return type (SQL text), which is useful but not deeply behavioral; it does not describe error cases or catalog assumptions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The core behavior is front-loaded, and the alternative tool is mentioned immediately after the main statement. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only metadata tool with rich annotations, the description is mostly complete: it states what is returned, scopes the operation to known views, and names the sibling for metadata. The main gap is the lack of parameter-level guidance for name/schema, but the overall shape is adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%, with only 'connection' described in the schema. The description does not explain the 'name' or 'schema' parameters or how they relate to the 'known view' concept, so it fails to compensate for the low coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Return') and resource ('SQL text that defines one known view or materialized view'), making the tool's function immediately clear. It also distinguishes itself from describeTable by explicitly routing metadata needs elsewhere.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear usage context: use this when you need the defining SQL of a known view/materialized view. It also names describeTable as the alternative when exposed fields, keys, or object metadata are needed, which is an explicit when-not condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

indexStatsindexStatsA
Read-onlyIdempotent

Inspect index definitions together with operational size, usage and cardinality counters for one table or a schema. Use describeTable for structural metadata of one table without live index statistics.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableNoOmit to scan the schema.
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
indexesNoIndexes available on the table or returned by an index-statistics scan.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and idempotentHint=true, so the safety profile is covered. The description adds context about the nature of the returned data (live counters) but does not describe pagination, empty-result behavior, or permission requirements. Given the annotation coverage, a 3 is appropriate – it adds some value but not extensive behavioral detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero redundancy: the first states the core purpose and scope, the second provides the key alternative. The most important information (what it does and its scope) is front-loaded, and every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only inspection tool with an output schema present, the description covers the essential use case and scope (table or schema), and explicitly points to the alternative when live stats are not needed. It omits any mention of performance implications or result size, but these are not critical for a tool of this type, and the annotations cover safety. The definition is sufficiently complete for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 67% (connection and table have descriptions, schema does not). The description clarifies that table is optional ('Omit to scan the schema') and that the tool works for 'one table or a schema', giving meaning to the schema parameter beyond the schema field. However, it does not explicitly document the schema parameter's format or interplay with table, so the compensation is partial. Baseline 3 is fair.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Inspect'), a clear resource ('index definitions'), and the precise data returned (operational size, usage, cardinality counters) for a table or schema. It explicitly differentiates itself from describeTable by contrasting 'live index statistics' with structural metadata, so an agent can distinguish it from a sibling without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use context (inspecting index stats) and names describeTable as the alternative for structural metadata without live stats. It does not address other index-focused siblings like unusedIndexes or redundantIndexes, but the primary differentiation is clear and the usage scenario is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

inspectQueryinspectQueryA
Read-onlyIdempotent

Inspect SQL syntax and structure without accessing a database. Returns a parser-derived AST summary of tables, aliases, expressions, joins, predicates, ordering, columns and parameters; use validateQuery for driver validation or queryLint for metadata-aware advice.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNo
joinsNoJoin clauses detected in the query.
tablesNoTable references extracted from the query, including CTEs and subqueries where possible.
aliasesNoMap of SQL alias to referenced table or expression.
columnsNoColumn references extracted from all inspectable SQL clauses.
explainNoTrue when the inspected statement is an EXPLAIN statement.
orderByNoORDER BY expressions in the query.
cteNamesNoCommon table expression names declared by the query.
featuresNo
warningsNoWarnings produced while parsing and inspecting the query.
parseableNoTrue when SQL parsing succeeded well enough to produce structured inspection data.
parametersNoSQL placeholders or documented query parameters.
predicatesNoPredicate expressions extracted from WHERE, JOIN, HAVING, and related scopes.
selectItemsNoExpressions in the SELECT list, in output order.
normalizedSqlNoNormalized SQL text produced by parser or usage-catalog indexing.
statementTypeNoTop-level SQL statement type detected by the parser.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint annotation, the description adds the significant behavioral detail that the tool does not access a database and that the result is parser-derived. It also lists what the AST summary contains, giving the agent accurate expectations of the tool's behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: purpose, behavioral claim, output, and alternatives all appear in one efficient sentence. Every clause earns its place, with no redundant elaboration.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter parser tool with an output schema and read-only annotations, this description is complete. It covers the tool's scope, output nature, and sibling alternatives, and the remaining connection nuance is at least partially handled by the schema's instructions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description explains what the SQL input is used for, but the connection parameter remains ambiguous: the schema says 'Database to run against' while the description says 'without accessing a database.' With only 50% schema description coverage, the description should clarify why the connection is needed despite no database access.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific action ('Inspect SQL syntax and structure') and a clear resource (SQL), and immediately distinguishes the tool from close siblings by listing what it returns and by naming validateQuery and queryLint as alternatives. An agent can tell exactly what this tool does without inspecting schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells the agent when not to use this tool: 'use validateQuery for driver validation or queryLint for metadata-aware advice.' This provides concrete routing among siblings and enough context to select inspectQuery for syntax/structure inspection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

invalidateUsageCatalogCacheinvalidateUsageCatalogCacheA
Read-onlyIdempotent

Force the server-local usage index to be rebuilt after its configured sources change. Invalidates only the runtime/local index; the next usage lookup rebuilds it synchronously and no inspected database data is modified.

ParametersJSON Schema
NameRequiredDescriptionDefault
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
stateNoCurrent usage-catalog index state, such as not_started, indexing, ready, or failed.
sourcesNoConfigured usage-catalog source paths and database-native sources considered for indexing.
indexingYesTrue while the usage catalog index is being built.
connectionNoName of the connection this catalog belongs to.
catalogEnabledYesFalse when the usage catalog is disabled; true when indexing and lookups are allowed.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false; the description reinforces this with 'no inspected database data is modified' and adds specifics about synchronous rebuild on next lookup, which is beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with purpose, no fluff. Every sentence contributes essential information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With one parameter, an output schema present, and annotations covering safety, the description fully covers purpose, trigger, scope, and behavior. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description already fully documents the single parameter at 100% coverage ('Call listConnections for valid names; do not guess'). The tool description adds no additional parameter context, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Force the server-local usage index to be rebuilt') and distinguishes the scope ('runtime/local index' only). Clearly differentiates from a full rebuild by noting it invalidates and rebuilds on next lookup.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a clear trigger ('after its configured sources change') and clarifies that it only affects the runtime/local index, implying when to use it over a full rebuild. However, it does not explicitly name alternative tools like rebuildCatalog.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

joinCardinalityjoinCardinalityA
Read-onlyIdempotent

Estimate the output size and selectivity of a proposed equi-join between two known tables without executing it. Returns planner estimates for both sides and versus the Cartesian product; use findJoinPaths when the join route itself is unknown.

ParametersJSON Schema
NameRequiredDescriptionDefault
toTableYes
joinTypeNoJoin type: INNER (default), LEFT, RIGHT, FULL
toSchemaNo
fromTableYes
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
fromSchemaNo
leftColumnYesColumn in fromTable.
rightColumnYesColumn in toTable.

Output Schema

ParametersJSON Schema
NameRequiredDescription
noteNoAdditional context about support, limits, interpretation, or engine-specific behavior.
toTableNoRight or joined target table for the join estimate.
joinTypeNoJoin type used for the estimate or parsed join, such as INNER, LEFT, RIGHT, or FULL.
toSchemaNo
fromTableNoLeft or preserved source table for the join estimate.
fromSchemaNo
leftColumnNoColumn from the source table used on the left side of the join estimate.
rightColumnNoColumn from the target table used on the right side of the join estimate.
cartesianRowsNoProduct of the two side row estimates before applying join selectivity.
estimatedRowsNoPlanner or catalog estimate of rows for this object or operation.
toRowEstimateNoPlanner row estimate for the target table before joining.
fromRowEstimateNoPlanner row estimate for the source table before joining.
selectivityVsCartesianNoEstimated join output divided by cartesian row count, from 0.0 to 1.0 when known.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, destructiveHint, and idempotentHint. The description adds behavioral value by stating it returns planner estimates (not actual results) and compares against the Cartesian product, which goes beyond the annotation. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler, purpose front-loaded, and the alternative is stated succinctly. Every word contributes.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a cardinality estimation tool, it covers the core behavior (what it estimates, that it doesn't execute, what it returns) and the key alternative. It does not mention error conditions or catalog prerequisites, but given the output schema is provided separately, it is sufficiently complete for an agent to use correctly in most cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 50%; the schema describes joinType, connection, leftColumn, and rightColumn, but not the table/schema parameters. The description mentions 'known tables' and 'equi-join' but does not clarify the meaning or relationship of parameters beyond what the schema already offers. It adds minimal value for parameter understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('estimate'), a specific resource ('output size and selectivity of a proposed equi-join between two known tables'), and explicitly notes it does not execute. It distinguishes itself from findJoinPaths by naming the alternative, making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides an explicit when-not condition ('use findJoinPaths when the join route itself is unknown'), giving clear usage context. However, it doesn't address other potential siblings like estimateSelectivity or analyzePlan, leaving some routing ambiguity for an agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listConnectionslistConnectionsA
Read-onlyIdempotent

Discover the databases served here and the valid name to pass as 'connection'. Call when the target connection is not already established; returns purpose, engine, default schema and local-catalog availability without opening a database connection.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
connectionsNoConfigured connections, in configuration order.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and no destructiveness. The description adds valuable behavioral context beyond annotations by stating it returns purpose, engine, default schema, and local-catalog availability, and notably that it works 'without opening a database connection.'

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler: the first states the core capability and output, the second gives a usage condition and return details. Information is front-loaded and every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless discovery tool with rich annotations and an output schema, the description fully explains what the tool does, when to call it, what behavior to expect, and what the results contain. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4. The description still adds useful semantic context by explaining that the output provides the valid name to pass as 'connection' to other tools.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Discover') and resource ('databases served here' and valid 'connection' names), clearly differentiating this discovery tool from siblings like listSchemas or listTables. It also specifies the exact output purpose: returning a valid name to pass as the 'connection' parameter.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit condition: 'Call when the target connection is not already established.' This implies the inverse case clearly, but it does not name alternative sibling tools or explicitly state when not to call beyond that condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listKnownDomainslistKnownDomainsA
Read-onlyIdempotent

Discover the existing business-domain vocabulary and query counts for reuse in listQueries filters.

ParametersJSON Schema
NameRequiredDescriptionDefault
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
domainsNoKnown business domains and their usage counts.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds behavioral value by disclosing that the result contains existing vocabulary and query counts, which is useful beyond the annotation-only picture.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence carries the purpose, the resource, and the intended reuse without any filler. Every word contributes, and the key discriminator ('for reuse in listQueries filters') appears at the end for natural reading.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only tool with one documented parameter, an output schema, and safety annotations, the description is complete enough. An agent can infer what it returns, why to call it, and that it is non-destructive without needing additional context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% for the single required parameter, and the schema already documents that 'connection' is a database name and instructs agents to call listConnections rather than guess. The tool description itself adds no parameter-level detail, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Discover') and a precise resource: 'existing business-domain vocabulary and query counts.' It also names the downstream use ('reuse in listQueries filters'), which clearly distinguishes it from plain enumeration tools like listKnownKinds or listKnownTags.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context by saying the output is meant for reuse in listQueries filters, so an agent knows when it is relevant. It does not explicitly say when not to use alternatives like listKnownKinds or listKnownTags, but the intended use case is specific enough to route selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listKnownKindslistKnownKindsA
Read-onlyIdempotent

Discover valid usage-catalog source-kind values and their query counts for reuse in listQueries filters.

ParametersJSON Schema
NameRequiredDescriptionDefault
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
kindsNoKnown source-kind values and their usage counts.

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, so the safety profile is covered. The description adds useful context by mentioning query counts and the usage-catalog source, but it does not disclose potential caveats like cache freshness or open-world value variability, which would have added more value.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence with no filler. Every phrase earns its place: what is discovered, what is included, and why the result matters.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter, read-only tool with a rich output schema and strong annotations, the description is complete. The agent knows when to call it, what it returns, and how the result should be used.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single connection parameter is well documented, including guidance to call listConnections for valid names. The description itself does not add new parameter-level meaning, but the schema already carries the full burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Discover') with a specific resource ('valid usage-catalog source-kind values and their query counts') and states the intended downstream use ('for reuse in listQueries filters'). This clearly differentiates it from sibling tools like listKnownDomains, listKnownTags, and listQueries.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly indicates when to use this tool: when valid source-kind values are needed for listQueries filters. It provides clear context but does not explicitly name alternatives or state when not to use it, so it stops short of the strongest guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listKnownTagslistKnownTagsA
Read-onlyIdempotent

Discover the existing business-tag vocabulary and query counts for reuse in listQueries filters.

ParametersJSON Schema
NameRequiredDescriptionDefault
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
tagsNoBusiness tags attached to the usage-catalog query.

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds no extra behavioral traits such as performance expectations, cache dependence, or return volume, but it doesn't contradict the annotations either.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence of 14 words, with the core action and resource front-loaded and the context at the end. There is zero filler; every word contributes to explaining what the tool does or why it should be used.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter, read-only discovery tool with a rich output schema and full annotation coverage, the description is complete. It tells the agent what will be returned (tag vocabulary and counts) and how to use it (for listQueries filters), leaving no critical gap for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter, connection, is fully documented in the schema with a description that even points to listConnections for valid values. The tool description adds no additional meaning beyond the schema, which has 100% coverage, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Discover') and resource ('business-tag vocabulary and query counts') and immediately states its integration purpose ('for reuse in listQueries filters'). This clearly distinguishes it from siblings like listKnownDomains and listKnownKinds, which handle other vocabularies.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear context for when to use the tool: when building filters for listQueries. However, it does not explicitly mention alternatives or when not to use it (e.g., when domains/kinds are needed), so it stops short of full exclusion guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listQuerieslistQueriesA
Read-onlyIdempotent

Browse or search stored usage-catalog queries by source, business metadata, parse status or free text. Returns summaries newest-ingest first; use getQuery for the complete SQL and evidence of one selected record.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagNoExact tag.
limitNoRows to return (default 100, max 1000).
offsetNoPaging offset (default 0).
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
searchTextNoCase-insensitive full-text search over SQL, labels, domains and source paths.
sourceKindNoSource kind, e.g. bi-publisher-report or dao.
sourcePathNoSource path LIKE pattern ('%'/'_').
parseStatusNoParse status: parsed or failed.
businessDomainNoExact business domain.

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNumber of query entries returned in this page.
limitYesRow limit applied to the query or page size requested by the caller.
offsetYesZero-based result offset for pagination, or true when SQL contains OFFSET depending on context.
queriesNoUsage-catalog query entries returned by the current filter or disabled-catalog response.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context beyond annotations by specifying that results are 'summaries newest-ingest first' and that the complete SQL and evidence require a follow-up getQuery call. This informs ordering and return granularity without contradicting the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The first sentence states the tool's purpose and filter dimensions; the second explains result ordering and directs the agent to getQuery for deeper detail. This is efficient, front-loaded, and every clause adds useful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only browsing/search tool, the description is complete: it explains the resource, the search dimensions, the result type ('summaries'), the sort order ('newest-ingest first'), and the relationship to getQuery for full detail. An output schema exists, so return-value details are not required in the description. Combined with the schema's thorough parameter documentation and the non-destructive annotations, an agent has everything needed to call this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3 because the schema already documents all nine parameters. The description does add a light conceptual grouping ('source, business metadata, parse status or free text'), but this mostly mirrors parameter names like sourceKind, sourcePath, businessDomain, parseStatus, and searchText. It does not introduce new semantic detail such as value formats, LIKE patterns, or interaction between filters beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Browse or search') on a specific resource ('stored usage-catalog queries') and lists the filtering dimensions: source, business metadata, parse status, and free text. It also distinguishes itself from getQuery by noting that listQueries returns summaries while getQuery provides complete SQL and evidence. This makes the tool's purpose immediately clear and separable from its siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for when to use the tool versus getQuery: use listQueries for browsing/searching summaries, then getQuery for full SQL and evidence of a selected record. It does not explicitly mention exclusions against searchObjects or other sibling search-like tools, but the emphasis on 'usage-catalog queries' implies the intended scope. The guidance is clear enough for an agent to make a sound initial selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listRoutineslistRoutinesA
Read-onlyIdempotent

Discover function, procedure and package names in a schema, optionally by name pattern. Use getRoutineDefinition when the source of one known routine is needed.

ParametersJSON Schema
NameRequiredDescriptionDefault
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
namePatternNoJDBC name pattern, e.g. '%calculate%'.

Output Schema

ParametersJSON Schema
NameRequiredDescription
routinesNoFunction, procedure, and package entries.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds value by specifying the resource types (functions, procedures, packages) and optional pattern filtering, which goes beyond annotations. It doesn't describe pagination or ordering, but output schema exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero waste. Purpose is front-loaded, and the alternative is given immediately after. Very efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a listing tool with an output schema and read-only annotations, the description covers key decision points: what is listed, optional pattern, and when to use the alternative. It doesn't mention pagination or limits, but those are likely in the output schema. It's sufficiently complete for an agent to call correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67%, so the baseline is 3. The description mentions 'in a schema' and 'by name pattern' which adds meaning to the schema and namePattern parameters. The connection parameter is documented in-schema with a directive to call listConnections. The schema parameter lacks in-schema documentation but is implied in the description, though not explicitly detailed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States 'Discover function, procedure and package names in a schema' – a clear verb, resource, and scope. It also explicitly distinguishes from getRoutineDefinition, making it easy to select the right tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use the alternative getRoutineDefinition ('when the source of one known routine is needed') and mentions the optional name pattern, which implies when to use it. Doesn't exhaustively cover all sibling listings but gives the primary decision.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listSchemaslistSchemasA
Read-onlyIdempotent

Discover schema names visible to the current user when the target schema is unknown. Use listTables next to enumerate objects in one schema.

ParametersJSON Schema
NameRequiredDescriptionDefault
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
includeSystemNoInclude system schemas. Default false.

Output Schema

ParametersJSON Schema
NameRequiredDescription
schemasNoSchema names.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, covering the safety profile. The description adds a small behavioral detail: it lists schemas 'visible to the current user,' which is helpful. It does not describe pagination, ordering, or potential system schema inclusion (though that is covered in the parameter). Given the annotations carry the main burden, a 3 is appropriate – the description adds some context but not rich behavioral detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no redundancy. The primary purpose is stated first, and the follow-up action is provided succinctly. Every word earns its place, and it is appropriately short for a simple discovery tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity tool with an output schema (not shown but indicated), the description covers when to use it, what it returns, and the next step. It lacks explicit mention of error handling or permissions, but the annotations cover safety. The only minor gap is not stating what happens if the schema is already known, but that is implicit in the phrase 'when the target schema is unknown.' Overall, it is complete enough for correct usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema covers 100% of parameters with descriptions, including guidance to call listConnections for valid names and the default for includeSystem. The tool description itself does not add parameter-level information beyond the purpose. Since the schema already provides the needed semantics, the baseline of 3 applies without additional value from the description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Discover') and resource ('schema names'), and clearly scopes the use case: 'when the target schema is unknown.' It also distinguishes itself from a sibling tool by mentioning listTables for the next step, making it unambiguous which tool to use for schema discovery versus object enumeration.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear condition for use ('when the target schema is unknown') and suggests a follow-up action ('Use listTables next'). It also indirectly references listConnections in the parameter description for valid connection names. However, it does not explicitly mention when not to use this tool or alternatives like searchObjects, though the context is fairly clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listSequenceslistSequencesA
Read-onlyIdempotent

Discover sequence names and metadata in one schema, or across all schemas when schema is omitted.

ParametersJSON Schema
NameRequiredDescriptionDefault
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
sequencesNoSequence entries.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry the safety profile (readOnlyHint, idempotentHint, destructiveHint=false), so the bar for the description is lower. The description adds the one non-obvious behavioral trait beyond those hints: the schema parameter is optional, and omitting it changes the result scope to 'across all schemas.' No contradiction with the annotations exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single 17-word sentence with the verb and resource front-loaded, followed by the scoping conditional. Every word earns its place — no filler and no repetition of what the schema or annotations already state.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 2-parameter, read-only discovery tool, the description plus an output schema and safety annotations cover everything an agent needs: connection-parameter behavior is in the schema, schema-omission behavior is in the description, and return values are covered by the output schema. Nothing required for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 50% — the schema parameter has no schema-level documentation. The description compensates by explaining the schema parameter's semantics ('in one schema, or across all schemas when schema is omitted'), telling the agent that omission is valid and changes the scope. The connection parameter is already documented in the schema, so the description need not repeat it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description pairs a specific verb ('Discover') with a precise resource ('sequence names and metadata') and states the scoping behavior ('in one schema, or across all schemas when schema is omitted'). This is a specific verb+resource that distinguishes it from sibling list tools like listSchemas, listTables, and listRoutines by its unique resource type.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The schema-scoping statement ('across all schemas when schema is omitted') gives useful context on how to invoke the tool for different result sets, and the resource name clarifies its niche relative to list* siblings. However, it never explicitly names alternatives or states when NOT to use it, leaving tool selection among the 50+ siblings to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listTableslistTablesA
Read-onlyIdempotent

Enumerate table and view names in a known schema, optionally filtered by name or type. Does not return fields/columns; use describeTable for one object's structure.

ParametersJSON Schema
NameRequiredDescriptionDefault
typesNoJDBC table types CSV (default TABLE,VIEW,MATERIALIZED VIEW): TABLE,VIEW,MATERIALIZED VIEW,SYSTEM TABLE,GLOBAL TEMPORARY,LOCAL TEMPORARY,ALIAS,SYNONYM
schemaNoOmit to use JDBC_DEFAULT_SCHEMA or the current schema.
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
namePatternNoJDBC pattern ('%' any, '_' one character).

Output Schema

ParametersJSON Schema
NameRequiredDescription
tablesNoTable and view entries.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnlyHint, idempotentHint, and destructiveHint false, so safety is covered. The description adds useful behavioral context beyond that: it returns only names, not columns, and supports optional filtering by name or type. This is modest but meaningful added disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero filler, and the core purpose is front-loaded in the first phrase. Every word contributes to clarifying scope or routing to an alternative.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only listing tool, the description covers purpose, filter options, and the key limitation (no columns). The output schema exists, and the parameter schema covers all inputs, so nothing essential for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters are fully documented in the schema itself. The description's phrase 'filtered by name or type' roughly maps to namePattern and types, but it adds no new semantic detail beyond what the schema already provides, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Enumerate') and names the resource ('table and view names'), with a clear scope ('in a known schema'). It also explicitly distinguishes itself from describeTable by stating it does not return fields/columns, which prevents confusion with a close sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-not guidance ('Does not return fields/columns') and names the specific alternative to use ('use describeTable for one object's structure'). This tells the agent exactly which tool to select for a different need.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

nullRationullRatioA
Read-onlyIdempotent

Find sparse or mostly-null fields across every column of one table in a single scan. Returns null/non-null counts and ratios sorted by sparsity; use describeTable when only declared nullability is needed.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableYes
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
tableNo
schemaNo
columnsNoPer-column null-ratio entries, sorted by descending null ratio.
totalRowsYesTotal number of rows considered for this statistic.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds valuable behavioral detail beyond that: it performs a single scan, scans every column, returns null/non-null counts and ratios, and sorts by sparsity. These are meaningful execution traits that help an agent anticipate behavior and cost. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, dense sentence that front-loads the core purpose, then specifies the output, then gives the routing alternative. There is zero fluff; every clause earns its place. It is highly efficient and easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (3 parameters, 2 required), the description covers purpose, output shape (counts, ratios, sorting), scope (every column, one table), and usage routing. An output schema exists, so return details are already structured. Nothing an agent needs to correctly invoke this tool is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33% (only the connection parameter has a description). The tool description does not add parameter-level semantics, but the parameter names (table, schema, connection) are self-explanatory, and the connection parameter has a useful schema description ('Call listConnections for valid names; do not guess'). The description implies that table and schema identify the target table, so the agent can infer usage. This is adequate but not enhanced beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Find') and resource ('sparse or mostly-null fields across every column of one table'), clearly stating what the tool does. It also differentiates from a sibling by naming describeTable as the alternative when only declared nullability is needed, so an agent can distinguish it without inspecting schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly tells the agent when to use this tool (when actual null counts/ratios are needed) and when to use the alternative ('use describeTable when only declared nullability is needed'). This is direct routing guidance that leaves no ambiguity about selection among siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

observedRelationshipsobservedRelationshipsA
Read-onlyIdempotent

Discover empirically observed equi-join column pairs from stored queries, with support counts and contributing query IDs. Use findJoinPaths for declared/combined paths between endpoints; non-equi joins are excluded.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableNoRequire either join side to use this table.
schemaNoCase-insensitive filter.
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
minSupportNoMinimum supporting queries (default 1).

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNumber of observed relationships returned after filtering.
tableNoOptional table filter used when aggregating observed relationships.
schemaNo
minSupportYesMinimum observed support threshold applied to relationship aggregation.
relationshipsNoRelationship edges relevant to the context, graph, or observed-relationships result.

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the agent knows this is a safe read operation. The description adds that it is 'empirically observed' from stored queries and that non-equi joins are excluded, which is useful context. However, it doesn't disclose details like whether results are paginated, how support counts are computed, or whether the catalog must be fresh. With annotations covering the safety profile, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero waste. The core purpose is front-loaded, and the alternative tool is named in the second sentence. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has an output schema, so the description needn't explain return values. The description covers purpose, scope, exclusions, and the alternative tool. The only minor gap is that it doesn't mention whether the results are limited to the current catalog or whether the catalog needs to be populated, but given the output schema and annotations, this is nearly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all four parameters. The description adds the context that the tool returns support counts and contributing query IDs, which helps understand the minSupport parameter's meaning, but it doesn't add syntax or format details beyond what the schema provides. Baseline 3 is correct when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Discover'), a specific resource ('empirically observed equi-join column pairs from stored queries'), and the output includes support counts and contributing query IDs. It also explicitly distinguishes itself from findJoinPaths, which is a sibling tool, by noting that findJoinPaths is for declared/combined paths and that non-equi joins are excluded. This makes the tool's purpose unambiguous and differentiates it from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Use findJoinPaths for declared/combined paths between endpoints; non-equi joins are excluded.' This provides clear when-to-use and when-not-to-use guidance, naming the alternative tool and the condition that selects it. The connection parameter also instructs to call listConnections for valid names, which is a usage guideline.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

queryContextqueryContextA
Read-onlyIdempotent

Build multi-table SQL-authoring context from natural-language terms or an explicit table list. Use when relevant tables are unknown or a request spans several tables; for one known table's fields or structure, use describeTable.

ParametersJSON Schema
NameRequiredDescriptionDefault
termsNoUser terms, e.g. 'customers order totals'.
schemaNo
tablesNoForce-include tables (CSV), e.g. customers,orders.
maxTablesNoTables to include (default 12).
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
includeSamplesNoInclude up to 3 rows per table (default false).

Output Schema

ParametersJSON Schema
NameRequiredDescription
termsNoNatural-language terms used to select relevant schema context.
schemaNo
tablesNoTables included in this context, graph, query inspection, or usage record.
joinPathsNoShortest or suggested join paths between selected tables.
tableCountYesNumber of tables selected into the query context.
relationshipsNoRelationship edges relevant to the context, graph, or observed-relationships result.
includeSamplesYesTrue when small sample rows were requested for selected tables.
requestedTablesNoExplicit table names requested by the caller for query context.
semanticMatchesNoTables matched by semantic usage-catalog terms before final context assembly (opaque).

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly/idempotent/non-destructive behavior, so the description need not repeat safety information. It adds behavioral context that this is a context-building/selection operation rather than a query or analysis operation, and clarifies the multi-table scope. It does not detail all internal behavior, but that is not required given the rich annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler, and the core operation plus the primary usage condition appear first. Every sentence earns its place by either defining the tool or guiding routing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only schema-introspection tool with an output schema, six parameters, and strong annotations, the description plus input schema fully cover selection and invocation. The only required parameter (connection) is marked required and referenced in its own schema description with a pointer to listConnections.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 83%, and the schema already documents terms, tables, maxTables, connection, and includeSamples. The description adds only a high-level mapping from terms/tables to the purpose, which is useful but not materially beyond the schema; baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description opens with a specific verb and object ('Build multi-table SQL-authoring context') and specifies two input modes (natural-language terms, explicit table list). It names describeTable as the alternative, so the tool is distinguishable from its closest sibling without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Use when relevant tables are unknown or a request spans several tables' gives explicit trigger conditions, and 'for one known table's fields or structure, use describeTable' gives an explicit exclusion and alternative. No inference is required.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

queryLintqueryLintA
Read-onlyIdempotent

Review authored SQL for advisory metadata and indexing problems without executing it. Reports unknown objects, SELECT *, conditionless joins, unindexed FKs and non-leading predicate/order columns; use validateQuery when database-driver acceptance is the question.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
lintableYesTrue when query lint could combine parsed SQL with metadata checks.
warningsNoWarnings produced by SQL inspection and metadata-aware lint checks.
inspectionNoParsed query inspection that underpins lint (opaque; the inspectQuery tool returns the typed form).
warningCountNoNumber of warnings produced by inspection or lint.
tablesCheckedNoTables whose metadata was checked during query lint.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, and non-destructive. The description adds valuable behavioral detail by listing the specific problem categories it reports (unknown objects, SELECT *, conditionless joins, etc.) and reiterates that it does not execute the SQL, which is consistent with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, dense sentence that front-loads the purpose and then enumerates the checks. It is efficient and well-structured, though the long list of issue types adds length without being verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the tool's purpose, scope, and a key alternative. An output schema exists, so return values are covered. However, the lack of parameter explanations (especially 'schema') and the absence of any prerequisite or connection context leave gaps for a 3-parameter tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33% (only 'connection' has a description). The tool description does not explain the 'sql' or 'schema' parameters, nor their relationship. With low schema coverage, the description should compensate, but it provides no parameter-level guidance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Review'), a specific resource ('authored SQL'), and a clear scope (advisory metadata and indexing problems). It also distinguishes itself from siblings by explicitly noting it does not execute the SQL, and names validateQuery as a specific alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit when-not condition ('use validateQuery when database-driver acceptance is the question') and implicitly narrows its use case to advisory checks. It does not cover all sibling distinctions, but the provided exclusion is clear and useful.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

rebuildCatalogrebuildCatalogA
Read-onlyIdempotent

Create or refresh the persistent local catalog for offline/repeated metadata and usage lookups. Captures configured schema metadata, rebuilds the usage index and returns the distributable catalog file; writes only server-local data, never the inspected database.

ParametersJSON Schema
NameRequiredDescriptionDefault
schemasNoSchemas to capture (CSV); omit for configured/default scope.
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
connectionNoName of the connection whose catalog was rebuilt.
catalogFileYesAbsolute path of the built catalog file on disk; copy this file to distribute the catalog.
structureSchemasNoSchemas captured into the structure snapshot.
usageSourceCountYesNumber of usage-catalog sources considered for indexing.
usageCatalogStateNoUsage-index state after the rebuild, e.g. not_started, indexing, ready, failed.
usageCatalogEnabledYesFalse when the usage catalog is disabled.
structureSchemaCountYesNumber of schemas captured into the structure snapshot.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds meaningful behavioral context beyond annotations: it writes server-local data, never the inspected database, and returns a distributable catalog file. This clarifies side effects and scope without contradicting the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The core action and key constraints are front-loaded, and the safety clarification ('writes only server-local data, never the inspected database') is placed at the end without bloating the description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is complete for a catalog-rebuild tool: it covers purpose, side effects, and output. It does not detail the return format, but an output schema exists, so that is not required. It could mention that the connection parameter is required, but the schema already marks it required, so the description does not need to repeat it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both parameters. The description adds context that 'schemas' is optional and defaults to configured scope, which is useful, but it does not add much beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Create or refresh') and a specific resource ('persistent local catalog'), and distinguishes it from the inspected database by clarifying it writes only server-local data. It also names the key outputs (metadata capture, usage index rebuild, distributable catalog file), which clearly differentiates it from siblings like usageCatalogStatus or invalidateUsageCatalogCache.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains when to use it ('for offline/repeated metadata and usage lookups') and what it does not do ('never the inspected database'). It does not explicitly name alternative tools or state when not to use it, but the context is clear enough for an agent to select it appropriately among the listed siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

redundantIndexesredundantIndexesA
Read-onlyIdempotent

Find structurally overlapping non-unique indexes whose leading columns are a strict prefix of another same-type index. Unlike unusedIndexes, this does not depend on workload scan counters.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableNoOmit to scan the schema.
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNumber of redundant-index findings returned.
tableNo
schemaNo
findingsNoSchema lint or redundant-index findings.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds meaningful behavioral context beyond those annotations: the analysis is structural, not workload-based, and only considers non-unique indexes with strict-prefix column overlap. There is no contradiction with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no wasted words. The core matching rule is front-loaded, and the contrast with unusedIndexes is brief but informative. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and annotations covering safety, the description provides enough detail about the tool's matching semantics to be actionable. The main gap is that schema/table scoping behavior is not fully elaborated in the description itself, though the schema partially covers it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema documents 'table' and 'connection' reasonably, but the 'schema' parameter has no description. The tool description itself does not clarify any parameter semantics or explain how table/schema/connection interact, so it fails to compensate for the undocumented parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Find structurally overlapping non-unique indexes' and gives a precise criterion: leading columns that are a strict prefix of another same-type index. It also differentiates the tool from unusedIndexes, so an agent can immediately tell this is the structural-redundancy analysis tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly names unusedIndexes as the sibling alternative and explains the deciding difference: 'this does not depend on workload scan counters.' This gives clear selection guidance for choosing between the two tools. It does not go further into when to scope by table or schema, but the core alternative choice is well covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resolveQueryLineageresolveQueryLineageA
Read-onlyIdempotent

Trace a query's data lineage from direct FROM/JOIN objects through views and optionally routines to underlying physical tables. Use inspectQuery for direct AST references only; routine expansion is best-effort and may miss dynamic SQL.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes
schemaNoDefault schema for unqualified names
maxDepthNoMaximum recursive expansion depth. Default 5, max 20.
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
expandViewsNoExpand database views and materialized views recursively. Default true.
expandRoutinesNoExpand database functions/procedures referenced by the query, best-effort. Default true.

Output Schema

ParametersJSON Schema
NameRequiredDescription
cyclesNoPossible relationship or lineage cycles found during traversal.
maxDepthYesMaximum relationship traversal depth that was applied.
warningsNoNon-fatal warnings produced while resolving or expanding lineage.
inspectionNoParsed query inspection that underpins lineage (opaque; the inspectQuery tool returns the typed form).
directObjectsNoObjects directly referenced by the query before recursive expansion.
expandedObjectsNoAll resolved objects visited during lineage expansion.
unresolvedObjectsNoObjects that could not be resolved against metadata during lineage analysis.
expandedPhysicalTablesNoPhysical tables reached by recursively expanding views and routines.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as read-only, idempotent, and non-destructive. The description adds valuable behavioral context beyond annotations: it traverses views and routines, can optionally expand routines, and is best-effort with potential misses on dynamic SQL. This gives an agent a realistic expectation of completeness.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loads the core behavior, and includes the key differentiator and caveat without waste. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity, the input schema covers defaults and constraints, annotations cover safety, and an output schema exists for return values. The description adds the essential behavioral scope and limitations, making the tool adequately specified for an agent to invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 83%, so the input schema already documents most parameters with meanings and defaults. The description adds context about 'views' and 'optionally routines' that maps loosely to expandViews and expandRoutines, but it doesn't substantially enhance parameter understanding beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action and resource: tracing a query's data lineage from direct FROM/JOIN objects through views and routines to physical tables. It explicitly differentiates from inspectQuery, which handles direct AST references only, making the tool's niche clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit guidance on when to use this tool versus inspectQuery: use inspectQuery for direct AST references only, and this tool for deeper lineage. It also discloses the limitation that routine expansion is best-effort and may miss dynamic SQL, helping an agent decide based on the query's nature.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sampleRowssampleRowsA
Read-onlyIdempotent

Preview a small number of actual rows from one known table or view to understand data shape and example values. For fields, types and constraints without reading row data, use describeTable.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoRows to return (default 10, max 100).
tableYes
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
rowsNoRows.
columnsNoColumns.
rowCountYesRow Count.
truncatedYesTruncated.
columnTypesNoColumn Types.

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds only that it returns 'actual rows' (versus schema/metadata), which is mildly useful context. It does not contradict annotations and does not add significant behavioral detail beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The core purpose is front-loaded in the first sentence, and the alternative guidance is in the second. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, idempotent tool with an output schema and safety annotations, the description is mostly sufficient. The main gap is the unexplained table parameter and the optional schema parameter, but the presence of an output schema and annotations covers return values and safety, making this only slightly incomplete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 50%: limit and connection are described, but table and schema are not. The description hints that the table must be 'known' but does not explain how to obtain or format table names, nor does it mention the optional schema parameter. This leaves required parameters under-documented and the description fails to compensate for the schema coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Preview a small number of actual rows from one known table or view.' It states the purpose (understanding data shape and example values) and explicitly distinguishes itself from describeTable, which is a sibling, making the tool's role unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear guidance on when to use this tool versus describeTable: use this to preview actual row data, use describeTable for fields, types, and constraints without reading rows. This is an explicit when/when-not pairing with a named alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

schemaBriefschemaBriefA
Read-onlyIdempotent

Discover candidate tables and views across a schema when their names are unknown. Returns a broad plain-text map with column counts, PKs and relationship summaries; follow with queryContext for multi-table authoring detail or describeTable for one known object.

ParametersJSON Schema
NameRequiredDescriptionDefault
termsNoTerms to narrow discovery; falls back to full schema on no match.
schemaNo
maxTablesNoTables/views to include (default 2000).
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnly, openWorld, idempotent, and non-destructive behavior. The description adds valuable context: it returns a 'broad plain-text map' (indicating output format) and implies a fallback to full schema when terms don't match (via the parameter description). It doesn't contradict annotations and enhances understanding of the tool's role as a discovery entry point.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero waste. The first sentence states the core purpose, and the second conveys output type and recommended follow-ups. The description is front-loaded with the key action and scope, then efficiently routes the agent to next steps.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a discovery tool with rich annotations, no output schema, and 4 parameters, the description fully covers purpose, usage, output format, and next steps. It also leverages parameter descriptions for connection validation and maxTables. Nothing critical for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 75% (terms, maxTables, connection have descriptions; schema does not). The tool description doesn't add parameter-specific meaning beyond what the schema already provides. Baseline for high coverage is 3; the description's mention of 'names are unknown' reinforces the terms parameter but doesn't add new semantic detail.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Discover'), a specific resource ('candidate tables and views across a schema'), and a clear condition ('when their names are unknown'). It also differentiates from siblings by mentioning follow-ups (queryContext, describeTable) and implies searchObjects/listTables are for known names. This is a distinct, non-tautological purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states the condition for using this tool ('when their names are unknown') and gives concrete follow-up actions ('follow with queryContext for multi-table authoring detail or describeTable for one known object'). This directly addresses when to use this tool versus alternatives, leaving no ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

schemaGraphschemaGraphA
Read-onlyIdempotent

Analyze schema-wide relationship topology: graph nodes/edges, central or isolated tables, components, cycle hints and an optional shortest path. Use findJoinPaths when only paths between two known tables are needed.

ParametersJSON Schema
NameRequiredDescriptionDefault
schemaNo
toTableNoOptional shortest-path target.
maxDepthNoShortest-path hops (default 4).
fromTableNoOptional shortest-path start.
maxTablesNoTables to scan (default 50).
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
edgesNoRelationship edges included in the graph response.
nodesNoTable nodes included in the schema graph response.
cyclesNoPossible relationship or lineage cycles found during traversal.
schemaNo
edgeCountYesTotal number of relationship edges in the graph response.
nodeCountYesNumber of table nodes in the schema graph.
shortestPathNo
centralTablesNoHighest-degree tables that are likely hubs in the schema.
tablesScannedYesNumber of tables inspected by the tool before caps were applied.
isolatedTablesNoTables with no visible relationships in the scanned schema graph.
declaredEdgeCountYesNumber of graph edges backed by declared foreign keys.
connectedComponentsNoConnected components discovered in the schema relationship graph.

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=true, and destructiveHint=false, so the read-only safety profile is fully covered. The description adds functional output details but not extra constraints or caveats such as scan limits affecting 'schema-wide' results; that context is only available in the maxTables parameter. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The core purpose is front-loaded and the sibling routing is placed at the end. Every sentence contributes meaningful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with an output schema, read-only annotations, and a clear sibling alternative, this is nearly complete. Minor gaps remain: the description doesn't clarify that the shortest-path inputs likely need both fromTable and toTable, and 'schema-wide' may be misleading given maxTables defaults to 50, though the parameter schema documents that.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is high (83%), so the schema carries most parameter meaning. The tool description adds a little by linking 'optional shortest path' to the fromTable/toTable parameters, but it does not clarify relationships between parameters (e.g., whether both from and to are needed for a path) or the meaning of the undocumented 'schema' parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Analyze') and resource ('schema-wide relationship topology'), and enumerates concrete outputs: graph nodes/edges, central or isolated tables, components, cycle hints, and optional shortest path. It also explicitly differentiates itself from findJoinPaths, so an agent can tell them apart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit alternative: 'Use findJoinPaths when only paths between two known tables are needed.' This clearly tells the agent when to prefer a sibling tool over schemaGraph, which is strong usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

schemaGraphDotschemaGraphDotA
Read-onlyIdempotent

Export a schema or selected tables as DOT/Graphviz ERD text with columns, types, PK/FK markers and join edges. Use schemaGraph for graph metrics rather than renderable diagram source.

ParametersJSON Schema
NameRequiredDescriptionDefault
schemaNo
tablesNoTables to include (CSV); omit for all.
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only, idempotent, and non-destructive behavior, so the bar for additional behavioral disclosure is lower. The description adds clarity about the tool's output format (DOT/Graphviz ERD text) and the fact that it returns diagram source rather than metrics, which meaningfully supplements the annotation-only picture.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The primary purpose and output details are in the first sentence, and the second sentence provides essential differentiation from schemaGraph. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple read-only export behavior, the description covers the key aspects an agent needs: what the output is, what it contains, and which sibling tool to choose instead. Minor omissions like how schema names should be formatted are partially covered by sibling listSchemas and the similar connection guidance, so the overall context is strong but not exhaustive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema documents the tables and connection parameters well, and the description clarifies that the tool can operate on 'a schema or selected tables', which gives semantic meaning to the schema and tables parameters. Only the schema parameter lacks an explicit schema-side description, but the tool-level wording mitigates this gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Export') and names the exact resource ('schema or selected tables as DOT/Graphviz ERD text'), plus enumerates content details like columns, types, PK/FK markers, and join edges. It also explicitly contrasts itself with schemaGraph, making the tool's distinct purpose immediately clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit alternative: 'Use schemaGraph for graph metrics rather than renderable diagram source.' This directly tells an agent when this tool is preferred and when schemaGraph would be better, which is strong routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

schemaLintschemaLintA
Read-onlyIdempotent

Audit one table or a schema for modeling and indexing risks: missing PKs, unindexed or mismatched FKs, nullable unique columns, missing CHECKs/remarks, orphan *_id columns, isolation and wide tables. Returns findings, not general table metadata.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableNoOmit to scan the schema.
checksNoChecks CSV, e.g. missingPrimaryKey,fkWithoutIndex; omit for defaults.
schemaNo
maxTablesNoTables to scan (default 50).
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
maxFindingsNoFindings to return (default 200).

Output Schema

ParametersJSON Schema
NameRequiredDescription
tableNo
checksNoSchema lint checks that were enabled for this audit.
schemaNo
findingsNoSchema lint or redundant-index findings.
truncatedYesTrue when the configured row or finding cap was reached and more data may exist.
findingCountYesNumber of lint findings returned or counted.
tablesScannedYesNumber of tables inspected by the tool before caps were applied.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only/idempotent/non-destructive behavior, and the description reinforces this with 'Audit' and 'Returns findings.' It adds useful output-level context ('findings, not general table metadata') and clarifies the access scope (one table vs a schema) without contradicting any annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, with the action and resource front-loaded and every clause contributing signal. The enumerated checks are compact and the return-type clarification earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is sufficient for a read-only audit tool, especially with a rich input schema and an output schema present. It could have added a bit more about how the checks mapping works or when limits apply, but the structured fields already cover those details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 83% schema coverage, the schema carries most parameter semantics, but the description adds a concrete catalog of what audits are performed, making the 'checks' parameter more understandable than the CSV example alone. The 'one table or a schema' phrasing also clarifies the table/schema targeting and the undocumented schema parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb ('Audit') and a concrete target ('one table or a schema'), and enumerates exact risk categories. The closing clause 'Returns findings, not general table metadata' differentiates it from metadata-style siblings such as describeTable or schemaBrief.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear use context: use when you need modeling/indexing risk findings, and the 'not general table metadata' line tells an agent not to use it for metadata retrieval. It stops short of explicitly naming alternatives like redundantIndexes, fkIndexCoverage, or queryLint, so it is not fully explicit about sibling choices.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

searchObjectssearchObjectsA
Read-onlyIdempotent

Find database objects when only a full or partial name is known. Searches non-system tables, views, routines, packages, sequences and synonyms case-insensitively; use describeTable after finding a table or view whose structure is needed.

ParametersJSON Schema
NameRequiredDescriptionDefault
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
namePatternYesName pattern — plain substring (auto-wrapped in %..%) or explicit pattern with % / _

Output Schema

ParametersJSON Schema
NameRequiredDescription
objectsNoMatching database objects across tables, views, routines, sequences, and synonyms.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is covered by structured data. The description adds genuinely useful behavior beyond that: the search is case-insensitive, excludes system objects, and the exact object types covered are enumerated. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero waste. The purpose is front-loaded in the first clause, the behavioral scope follows immediately, and the follow-up tool recommendation is tacked on efficiently. Every element earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete for a search tool. Output schema covers return values, annotations cover the safety profile, both required parameters are documented, and the description covers purpose, scope, case-sensitivity, and follow-up guidance. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters are fully documented in the schema itself — the description need not repeat format details. The description's 'full or partial name' phrasing does reinforce the namePattern semantics (substring vs. explicit pattern), which is helpful context, but adds only marginal value over the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Find database objects') and immediately scopes the behavior: 'Searches non-system tables, views, routines, packages, sequences and synonyms case-insensitively'. This clearly distinguishes it from sibling listing tools like listTables and listRoutines, which enumerate all objects, versus this one which searches by name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The trigger condition is stated explicitly: use it 'when only a full or partial name is known'. It also names the follow-up action ('use describeTable after finding a table or view whose structure is needed'). It stops short of explicitly excluding enumeration tools like listTables/listRoutines for exhaustive discovery scenarios, so it's clear but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

tableContexttableContextA
Read-onlyIdempotent

Explore the relationship neighborhood of one known table: compact root/nearby table metadata plus declared FK and optional observed join edges. Use when nearby joins are needed; for only the table's own fields or structure, use describeTable.

ParametersJSON Schema
NameRequiredDescriptionDefault
depthNoFK depth (default 1).
tableYes
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
includeStatsNoInclude row/size/activity stats (default false).
includeIncomingNoInclude child references (default true).
includeObservedNoInclude declared/observed/semantic usage evidence (default: catalog enabled).

Output Schema

ParametersJSON Schema
NameRequiredDescription
depthYesRelationship expansion depth from the root object.
tablesNoTables included in this context, graph, query inspection, or usage record.
rootTableNoRoot table requested for table context.
rootSchemaNoSchema of the root table requested for table context.
includeStatsYesTrue when live table statistics were requested for context tables.
relationshipsNoRelationship edges relevant to the context, graph, or observed-relationships result.
includeIncomingYesTrue when tables that reference the root table were included.
includeObservedYesTrue when usage-catalog observed joins were included as relationship evidence.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, open-world, idempotent, and non-destructive behavior, so the description does not need to repeat that. It adds context beyond annotations by specifying that output is 'compact root/nearby table metadata' with 'declared FK and optional observed join edges,' which conveys scope and non-exhaustiveness.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler; the core behavior is front-loaded before the usage guidance. Every clause earns its place by conveying scope, output content, and when to prefer a sibling tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the read-only annotations, the output schema, and schema-covered parameters, the description provides enough to invoke the tool correctly. It could be slightly more complete by noting default depth or the connection requirement, but those are already covered in the input schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 71%, and most parameters (depth, connection, includeStats, includeIncoming, includeObserved) already have descriptions in the schema. The description adds high-level context like 'declared FK and optional observed join edges' that maps to includeObserved, but it does not explain individual parameters, so it mostly relies on the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Explore the relationship neighborhood of one known table' and names the concrete outputs ('declared FK and optional observed join edges'). It explicitly distinguishes itself from describeTable ('for only the table's own fields or structure'), so an agent can tell siblings apart without inspecting schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear selection rule: 'Use when nearby joins are needed' and states the alternative for a different need ('for only the table's own fields or structure, use describeTable'). This tells the agent both when to invoke this tool and when not to, with a named fallback.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

tableStatstableStatsA
Read-onlyIdempotent

Inspect operational size and activity statistics for one known table: estimated/live rows, storage, dead tuples, maintenance times and scan counters. For fields, keys and constraints, use describeTable; available statistics depend on engine and privileges.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableYes
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNoError encountered while loading table statistics; other fields may be partial when set.
foundYesTrue when the requested object or path was found.
tableNo
blocksNoEngine-reported allocated block count, when available.
schemaNo
tupDelNoNumber of deleted tuples recorded by engine statistics.
tupInsNoNumber of inserted tuples recorded by engine statistics.
tupUpdNoNumber of updated tuples recorded by engine statistics.
idxScanNoNumber of index scans recorded for the table.
relkindNoEngine-specific relation kind for the table or view.
seqScanNoNumber of sequential scans recorded for the table.
avgRowLenNoAverage row length reported by optimizer statistics, when available.
temporaryNoWhether the table is temporary, when the engine reports it.
userStatsNoOracle flag indicating whether user-defined statistics are present.
chainCountNoOracle chained row count, when available.
createDateNoSQL Server object creation timestamp, when available.
deadTuplesNoEstimated number of dead tuples or obsolete row versions.
lastVacuumNoTimestamp of the last manual vacuum, when available.
liveTuplesNoEstimated number of live tuples or rows.
modifyDateNoSQL Server object modification timestamp, when available.
sampleSizeNoSample size used for optimizer statistics, when available.
seqTupReadNoNumber of tuples read by sequential scans.
compressionNoCompression setting reported for the table, when available.
emptyBlocksNoEngine-reported empty block count, when available.
globalStatsNoOracle flag indicating whether global statistics are present.
idxTupFetchNoNumber of table tuples fetched through this index, when available.
isFiletableNoSQL Server flag indicating a FileTable.
lastAnalyzeNoTimestamp of the last manual analyze/statistics collection, when available.
partitionedNoWhether the table is partitioned, when the engine reports it.
deadTuplePctNoApproximate percentage of dead tuples among total tuples.
lastAnalyzedNoTimestamp when database optimizer statistics were last collected, when available.
segmentBytesNoOracle segment size in bytes, when segment metadata is accessible.
estimatedRowsNoPlanner or catalog estimate of rows for this object or operation.
lastAutovacuumNoTimestamp of the last automatic vacuum, when available.
tableSizeBytesNoStorage used by the table heap or base data, in bytes.
toastSizeBytesNoPostgreSQL TOAST storage used by the table, in bytes.
totalSizeBytesNoTotal storage used by the table, indexes, and auxiliary storage, in bytes.
lastAutoanalyzeNoTimestamp of the last automatic analyze/statistics collection, when available.
indexesSizeBytesNoStorage used by indexes on the table, in bytes.
temporalTypeDescNoSQL Server temporal table type description.
isMemoryOptimizedNoSQL Server flag indicating a memory-optimized table.
segmentBytesErrorNoPermission or lookup error encountered while reading segment size.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds the engine/privilege dependency, which is useful context about what stats may be available. It doesn't disclose performance or error behavior, but that's less critical given the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler. The core purpose is front-loaded, and the alternative is given in a separate clause. Every part serves a purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple 3-parameter tool with an output schema, the description covers the essential purpose and a key caveat. It lacks explicit parameter guidance, but the schema and output schema fill in the rest. It is adequate for a well-scoped tool, though a bit more on parameter semantics would make it fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has only 33% description coverage (only connection is described). The description does not elaborate on 'table', 'schema', or 'connection' beyond what their names imply. It mentions 'one known table' but doesn't explain required vs optional parameters or how to specify schema. With low schema coverage, the description should compensate but does not, leaving parameter meaning thin.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states it inspects operational size and activity statistics for a known table, listing specific metrics (rows, storage, dead tuples, maintenance, scans). It differentiates from describeTable by noting that tool covers fields/keys/constraints, so a clear purpose and distinction from siblings is provided.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit alternative for a different task ('For fields, keys and constraints, use describeTable'), which helps route the agent. It also cautions that stats depend on engine/privileges, implying context-dependent behavior. It doesn't mention when to prefer this over other stats tools like indexStats or columnStats, but the primary guidance is present.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

timedQuerytimedQueryA
Read-onlyIdempotent

Measure one read-only SQL SELECT / WITH / EXPLAIN while still returning its rows and elapsed time. Use executeQuery when timing is irrelevant or benchmarkQuery for repeated cold/warm measurements. Bind '?'->params, ':name'->namedParams; never mix. E.g. :status -> namedParams={status:'PAID'} — key is the bare name. Adds available per-statement counter deltas (calls, execution time, rows, buffer hits/reads).

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes
limitNoRow limit (default JDBC_MAX_ROWS).
paramsNoValues for '?' placeholders, in order.
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
namedParamsNoValues for ':name' placeholders, keyed by name.
timeoutSecondsNoTimeout in seconds (default JDBC_QUERY_TIMEOUT_SECONDS).

Output Schema

ParametersJSON Schema
NameRequiredDescription
rowsNoReturned result rows as column-name to value maps, capped by the requested limit.
engineNoDatabase engine that produced the result, such as PostgreSQL, Oracle, or SQL Server.
columnsNoResult column names in output order.
rowCountYes
elapsedMsYesWall-clock elapsed time for the query execution, in milliseconds.
truncatedYesTrue when the configured row or finding cap was reached and more data may exist.
columnTypesNoDatabase type names for the result columns, in the same order as columns.
pgStatStatementsNo

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint, idempotentHint, and non-destructive hints. The description adds meaningful behavior beyond that: it returns both rows and elapsed time, reports per-statement counter deltas, and warns against mixing '?' and ':name' placeholder styles. This gives the agent useful operational expectations without contradicting the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose, immediately names alternatives, and then gives binding guidance with a concrete example. Every sentence adds distinct information and there is no filler or repetition of schema fields.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the tool's purpose, when to use alternatives, parameter binding conventions, and supplementary return information. Given the output schema exists and annotations cover safety, the description is complete enough for an agent to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 83%, so the schema already documents most parameters. The description adds valuable semantics by explaining the mapping of '?' to params and ':name' to namedParams, giving an explicit example, and stating that keys should be the bare name. This resolves ambiguity that the raw schema does not fully cover.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a precise action and resource: measuring a single read-only SQL SELECT/WITH/EXPLAIN while returning rows and elapsed time. It also differentiates itself from executeQuery and benchmarkQuery by referencing them explicitly, so an agent can distinguish this tool from its closest siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit routing guidance: use executeQuery when timing is irrelevant and benchmarkQuery for repeated cold/warm measurements. It also clarifies the one-shot nature of this tool ('Measure one') and provides binding rules, making the intended usage context very clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unusedIndexesunusedIndexesA
Read-onlyIdempotent

Find non-PK/non-unique indexes with zero recorded scans as removal candidates. Unlike redundantIndexes, this uses workload counters, which are meaningful only after representative traffic and are not supported by every engine.

ParametersJSON Schema
NameRequiredDescriptionDefault
schemaNo
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
minSizeBytesNoMinimum size in bytes; omit tiny indexes.

Output Schema

ParametersJSON Schema
NameRequiredDescription
noteNoAdditional context about support, limits, interpretation, or engine-specific behavior.
countYesNumber of unused indexes returned.
schemaNo
indexesNoIndexes available on the table or returned by an index-statistics scan.
supportedYesTrue when this tool is supported for the current database engine and privileges.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false. The description adds useful behavioral context beyond these annotations by revealing reliance on workload counters and their limitations, which is important for interpreting results correctly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two efficient sentences front-load the core purpose and then add a differentiating caveat. Every word contributes value, with no redundant restatement of the tool name or schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema, clear parameter documentation for most fields, and annotations already covering safety, the description supplies the remaining essential context: what the tool looks for, how it differs from a sibling, and when its results are valid. Nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents connection and minSizeBytes with descriptions, covering 67% of parameters. The description does not add new meaning about parameters; the only undocumented parameter 'schema' is not clarified in the description either, leaving a modest gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Find') and a clearly defined resource: non-PK/non-unique indexes with zero recorded scans, framed as removal candidates. It also explicitly differentiates itself from redundantIndexes, so an agent can distinguish the tool without inspecting schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description names redundantIndexes as the alternative and explains that this tool relies on workload counters, which are only meaningful after representative traffic and not supported by every engine. It provides clear context for when the tool is appropriate, though it does not give an explicit 'when not to use' list.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

usageCatalogStatususageCatalogStatusA
Read-onlyIdempotent

Check whether the usage catalog is enabled and ready before relying on observed-query or semantic evidence. Returns configured sources, indexing state, counts and load errors without searching for queries.

ParametersJSON Schema
NameRequiredDescriptionDefault
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.

Output Schema

ParametersJSON Schema
NameRequiredDescription
stateNoCurrent usage-catalog index state, such as not_started, indexing, ready, or failed.
sourcesNoConfigured usage-catalog source paths and database-native sources considered for indexing.
indexingYesTrue while the usage catalog index is being built.
connectionNoName of the connection this catalog belongs to.
catalogEnabledYesFalse when the usage catalog is disabled; true when indexing and lookups are allowed.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, covering the safety profile. The description adds value beyond that by disclosing exactly what an agent can expect to learn from the call: configured sources, indexing state, counts, and load errors. This behavioral detail is useful context not present in annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler. The purpose is front-loaded with the exact decision point ('before relying on observed-query or semantic evidence'), and the second sentence efficiently enumerates return contents. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity status tool with one documented parameter, a full output schema, and safety annotations, the description is nearly complete. The only slight gap is that it doesn't explain what the 'usage catalog' is or how it gets populated, but that is unlikely to prevent correct invocation given the explicit readiness framing and rich output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: the only parameter, connection, already has a clear description with guidance to call listConnections and not guess. The tool description itself adds no extra parameter detail, so a baseline 3 is appropriate; the schema carries the full semantic burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('check whether enabled and ready') and a specific resource ('usage catalog'), and distinguishes itself from query-searching tools with 'without searching for queries'. It also states the exact return contents (configured sources, indexing state, counts, load errors), making the tool's purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells the agent when to call this tool: before relying on observed-query or semantic evidence, as a readiness gate. It does not name alternative sibling tools, but the 'without searching for queries' phrase clarifies that this is not a query-lookup tool, and the sibling list contains obvious alternatives like findQueriesByTable and listQueries.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validateQueryvalidateQueryA
Read-onlyIdempotent

Check whether the database driver accepts a SELECT / WITH / EXPLAIN without executing it: prepares the statement and validates parameters, syntax and referenced objects. Use inspectQuery for parser-only AST inspection or queryLint for advisory metadata/index warnings. Bind '?'->params, ':name'->namedParams; never mix. E.g. :status -> namedParams={status:'PAID'} — key is the bare name.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes
paramsNoPositional parameters for '?' placeholders, in order. Required when SQL contains '?'.
connectionYesDatabase to run against. Call listConnections for valid names; do not guess.
namedParamsNoNamed parameters for ':name' placeholders. Required when SQL contains ':name'.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNo
stageNoValidation stage that failed, such as guard, params, or driver.
validYesTrue when the statement passed guard, parameter, and driver validation.
columnsNoNumber of result columns reported by driver validation when available.
inspectionNoParsed query inspection that underpins validation (opaque; the inspectQuery tool returns the typed form).
parametersNoNumber of SQL parameters expected or validated.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false. The description adds substantial behavioral detail beyond those: 'without executing it', 'prepares the statement', and the specific validation dimensions (parameters, syntax, referenced objects). There is no contradiction with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact, front-loaded with the core action, then adds sibling routing and binding details in two tightly written sentences plus an example. No filler or repetition of schema content; every sentence contributes distinct decision-relevant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no explanation. The description covers what the tool does, what it does not do (execute), how to choose between siblings, and how to bind parameters. Combined with annotations and schema descriptions, an agent has all necessary context to call this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents params and namedParams with clear semantics. The description adds value by explaining the mapping between '?' and ':name' placeholders, warning against mixing, and providing a concrete example where the key is the bare name. The sql parameter itself lacks a schema description, but the tool's purpose statement ('SELECT / WITH / EXPLAIN') gives adequate implied meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Check whether the database driver accepts a SELECT / WITH / EXPLAIN without executing it.' It then details what validation covers (parameters, syntax, referenced objects) and explicitly contrasts with inspectQuery and queryLint, making the tool's unique role unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives direct routing guidance: use inspectQuery for parser-only AST inspection, and queryLint for advisory metadata/index warnings. It also provides binding rules ('never mix') and a concrete example, so the agent knows exactly when and how to invoke this tool versus alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 49 tool updatesv0.1.0
    • First observedanalyzePlan
    • First observedbenchmarkQuery
    • First observedcolumnDistribution
    • First observedcolumnHistogram
    • First observedcolumnStats
    • First observeddescribeTable
    • First observedestimateSelectivity
    • First observedexecuteQuery
    • First observedexplainQuery
    • First observedfindJoinPaths
    • First observedfindQueriesByColumn
    • First observedfindQueriesByTable
    • First observedfkIndexCoverage
    • First observedgetQuery
    • First observedgetRoutineDefinition
    • First observedgetTriggerDefinition
    • First observedgetViewDefinition
    • First observedindexStats
    • First observedinspectQuery
    • First observedinvalidateUsageCatalogCache
    • First observedjoinCardinality
    • First observedlistConnections
    • First observedlistKnownDomains
    • First observedlistKnownKinds
    • First observedlistKnownTags
    • First observedlistQueries
    • First observedlistRoutines
    • First observedlistSchemas
    • First observedlistSequences
    • First observedlistTables
    • First observednullRatio
    • First observedobservedRelationships
    • First observedqueryContext
    • First observedqueryLint
    • First observedrebuildCatalog
    • First observedredundantIndexes
    • First observedresolveQueryLineage
    • First observedsampleRows
    • First observedschemaBrief
    • First observedschemaGraph
    • First observedschemaGraphDot
    • First observedschemaLint
    • First observedsearchObjects
    • First observedtableContext
    • First observedtableStats
    • First observedtimedQuery
    • First observedunusedIndexes
    • First observedusageCatalogStatus
    • First observedvalidateQuery

TDQS

A3.9/5.0

Scored across 49 tools

Disambiguation3/5

The tool set is generally well-separated, but there are several close clusters: query inspect/validate/lint/lineage, explain/analyze plan, columnStats/distribution/histogram, and redundant/unused/FK index tools. Descriptions and cross-references mostly disambiguate them, but with 49 tools an agent can still plausibly select the wrong member of such a cluster.

Naming Consistency4/5

Names are uniformly lowerCamelCase and mostly follow a readable verb+object pattern like listTables, getViewDefinition, and executeQuery. Some noun-first names like schemaGraph, columnStats, and tableContext form a consistent secondary style rather than chaotic mixing, so the naming remains predictable.

Tool Count2/5

49 tools far exceeds the 25-tool threshold for a well-scoped server. Many tools are highly granular variants—three column-stat tools, several query-analysis tools, and multiple index-audit tools—that could reasonably be consolidated, making the overall surface heavy for an agent.

Completeness4/5

For a read-only JDBC introspection and query-analysis server, coverage is very thorough: object discovery, metadata, sampling, relationships, query execution, plan diagnosis, index auditing, and usage-catalog lifecycle are all represented with few dead ends. Minor gaps such as table DDL generation or bulk cross-schema listing are workable via existing tools.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    F
    maintenance
    Read-only MCP server for SQL databases (SQL Server, Postgres, SQLite) with multi-server support and three-layer safety using AST validation and linting.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Read-only MCP server for querying PostgreSQL, MySQL, and SQLite from AI agents — multi-database, safe by default.
    4
    17 npm
    1
    ISC
  • F
    license
    Not graded
    quality
    C
    maintenance
    Read-only MCP server that lets coding AI agents inspect Oracle Database schema through live metadata.
    -