jdbc-mcp-server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| JDBC_MCP_DATA_DIR | No | Directory for local catalogs and logs (default: ~/.jdbc-mcp-server) | |
| JDBC_MCP_CONNECTIONS_FILE | No | Path to connections.json describing the databases to serve (default: ~/.jdbc-mcp-server/connections.json) |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": true
} |
| resources | {
"subscribe": false,
"listChanged": true
} |
| completions | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| rebuildCatalogA | 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. |
| benchmarkQueryA | 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. |
| timedQueryA | 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). |
| listConnectionsA | 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. |
| columnDistributionA | 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. |
| columnHistogramA | 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. |
| columnStatsA | 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. |
| estimateSelectivityA | 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. |
| joinCardinalityA | 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. |
| nullRatioA | 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. |
| describeTableA | 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. |
| getRoutineDefinitionA | Return the source code of one known function, procedure or package, including its body where available. Use listRoutines to discover routine names. |
| getTriggerDefinitionA | Return the full definition/body of one known table trigger. For trigger names and compact metadata, use describeTable first. |
| getViewDefinitionA | Return the SQL text that defines one known view or materialized view. For its exposed fields, keys and other object metadata, use describeTable. |
| listRoutinesA | Discover function, procedure and package names in a schema, optionally by name pattern. Use getRoutineDefinition when the source of one known routine is needed. |
| listSchemasA | Discover schema names visible to the current user when the target schema is unknown. Use listTables next to enumerate objects in one schema. |
| listSequencesA | Discover sequence names and metadata in one schema, or across all schemas when schema is omitted. |
| listTablesA | 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. |
| searchObjectsA | 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. |
| analyzePlanA | 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. |
| explainQueryA | 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. |
| inspectQueryA | 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. |
| queryLintA | 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. |
| resolveQueryLineageA | 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. |
| validateQueryA | 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. |
| executeQueryA | 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. |
| sampleRowsA | 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. |
| findJoinPathsA | 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. |
| queryContextA | 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. |
| schemaBriefA | 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. |
| schemaGraphA | 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. |
| schemaGraphDotA | 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. |
| schemaLintA | 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. |
| tableContextA | 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. |
| fkIndexCoverageA | 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. |
| indexStatsA | 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. |
| redundantIndexesA | 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. |
| tableStatsA | 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. |
| unusedIndexesA | 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. |
| findQueriesByColumnA | 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. |
| findQueriesByTableA | 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. |
| getQueryA | 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. |
| invalidateUsageCatalogCacheA | 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. |
| listKnownDomainsA | Discover the existing business-domain vocabulary and query counts for reuse in listQueries filters. |
| listKnownKindsA | Discover valid usage-catalog source-kind values and their query counts for reuse in listQueries filters. |
| listKnownTagsA | Discover the existing business-tag vocabulary and query counts for reuse in listQueries filters. |
| listQueriesA | 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. |
| observedRelationshipsA | 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. |
| usageCatalogStatusA | 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. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 49 tools
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.
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.
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.
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.