MCP server for connecting to Google Ad Manager via JDBC using CData drivers
This MCP server exposes three read-only SQL-based tools for querying Google Ad Manager via a JDBC driver. Tool names follow verb_noun convention (get_tables, get_columns, run_query), which is positive. However, there are critical gaps: parameter descriptions are minimal or missing context, output schemas are not documented in the code, and error handling is primitive (generic RuntimeException with message concatenation). The run_query tool's description contains an internal logical error ('Use the `run_query` tool to get a list of available tables', should reference get_tables). CSV output format is mentioned but the structure and fields returned are not formally documented. No parameter constraints (enums, ranges, formats) are visible. The tools are READ_ONLY and well-scoped, but lack the production-grade detail needed for confident LLM reasoning.
Retrieves a list of fields, dimensions, or measures (as columns) for an object, entity or collection (table). Use the `get_tables` tool to get a list of available tables. The output of the tool will be returned in CSV format, with the first line containing column headers.
Retrieves a list of objects, entities, collections, etc. (as tables) available in the data source. Use the `get_columns` tool to list available columns on a table. Both `catalog` and `schema` are optional parameters. The output of the tool will be returned in CSV format, with the first line containing column headers.
Execute a SQL SELECT statement.
run_query description is internally inconsistent and misleading. It states 'Use the `run_query` tool to get a list of available tables, and the `run_query` tool to list table columns', both should reference get_tables and get_columns respectively. This will confuse LLMs about tool dependencies.
Output schemas are not documented anywhere in the visible code. All three tools return CSV format with 'first line containing column headers', but the actual field names, types, and meanings are not formally specified. LLMs cannot plan downstream operations without knowing what fields to expect.
Parameter descriptions are either missing or inadequate. 'catalog', 'schema', and 'table' parameters have one-word descriptions ('The catalog name', 'The schema name', 'The table name'). No guidance on format, allowed values, or when they are required vs. optional. The run_query 'sql' parameter description is verbose but contains error and lacks examples of valid SQL dialects or quoted identifier syntax.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 41 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 38 | - | v1 |
Error handling is minimal. The code catches all exceptions and rethrows a RuntimeException with message concatenation ('ERROR: ' + ex.getMessage()). No error classification, recovery guidance, or actionable detail. If a query fails due to invalid SQL, the LLM sees only the raw exception message, not what to do next.
No parameter constraints visible. The 'sql' parameter accepts free-form strings with no schema validation, regex pattern, or format constraint. The description lists allowed clauses (FROM, INNER JOIN, etc.) but these are not enforced in schema, LLMs may attempt unsupported syntax like UPDATE or DELETE.
Missing pagination and result limit guidance. If get_tables or run_query returns thousands of rows, there is no limit parameter, offset/page parameter, or result cap documented. CSV output with no pagination can exhaust context window and degrade LLM reasoning.