Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
This MCP server provides three read-only database tools with basic definitions. Tools are registered with proper schemas and descriptions present, but descriptions are generic and lack guidance for LLM decision-making. Schemas are syntactically present but lack validation details, constraints, and output documentation. No error handling guidance, no tool annotations, no composition hints. Per-tool averages: get_tables (55), get_columns (58), run_query (44).
Tools (3)
get_columnsread only50/100
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.
get_tablesread only50/100
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.
run_query tool has vague name ('run_query' is generic; 'execute_sql' or 'query_database' is clearer). Description references 'Use the `run_query` tool' twice (copy-paste error) instead of `get_tables` and `get_columns`. Description omits what a SELECT statement returns (structure, field names, limits).
Output schemas are completely undocumented. Code returns CSV format with headers, but tool descriptions do not state return type, field structure, or pagination behavior. LLMs cannot plan downstream calls without knowing what fields come back.
No input validation constraints documented. Parameters like 'catalog', 'schema', 'table', 'sql' lack type constraints, length limits, or allowed patterns. run_query description mentions 'SQL-92' dialect and valid clauses, but this belongs in the parameter description, not as a note to users.
get_tablesget_columnsrun_query
Recommendations
Rename 'run_query' to 'execute_sql_query' or 'query_database' to match verb_noun convention and reduce ambiguity. 'run' is a generic verb that does not convey intent.
Fix run_query description: remove duplicate reference to 'run_query', replace with 'get_tables' and 'get_columns'. State that output is CSV with headers and field names match SQL column aliases.
Document return schemas for all three tools. For get_tables, state: 'Returns CSV with columns: [TABLE_CAT, TABLE_SCHEM, TABLE_NAME] depending on database. First row is headers.' For get_columns: 'Returns CSV with columns: [TABLE_CAT, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, TYPE_NAME, REMARKS] depending on database.' For run_query: 'Returns CSV with column headers matching query SELECT clause.'
Add input constraints to parameter descriptions. For 'sql': 'SELECT statements only. Supports FROM, INNER JOIN, LEFT JOIN, GROUP BY, ORDER BY, LIMIT/OFFSET. Identifiers must be quoted with double quotes. Max 10000 characters.' For 'table': 'Required. Must exist in the database. Case-sensitive. May require schema qualification if not in default schema.'
Add WHEN-to-use guidance to each description. For get_tables: 'Call this first to discover available tables in the database. Use optional catalog and schema to filter results.' For get_columns: 'Call after identifying a table with get_tables. Returns column names, data types, and descriptions needed to construct valid queries.' For run_query: 'Use to fetch data matching specific criteria. Call get_tables and get_columns first to identify valid table and column names.'
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
No error handling or recovery guidance. Code throws RuntimeException('ERROR: ' + ex.getMessage()) with no guidance for the LLM. What should it do if a table is not found? If a column name is invalid? If a query times out?
Tool descriptions lack WHEN-to-use guidance. 'Retrieves a list of objects...' does not tell the LLM when to prefer get_tables over run_query, or why to call get_columns first. No dependency hints or discovery patterns documented.
No tool annotations (toolAnnotations=false). These are read-only tools that never modify data, marking them with readOnlyHint would signal to LLMs and clients that they are safe to call without confirmation or logging for side effects.
No pagination or result limits documented. run_query and get_tables can return unbounded lists. If a database has 10,000 tables or a query matches 100,000 rows, the CSV response could explode context window. No limit parameter, no cursor, no total count.
get_tablesget_columnsrun_query
Implement result limits and pagination. Add optional 'limit' parameter (default 100, max 1000) to all three tools. For get_tables and run_query, add 'offset' parameter to support pagination. Return a 'next_offset' or 'has_more' field in response metadata so LLMs know when to fetch additional pages.
Add error recovery guidance in descriptions. Example for run_query: 'If query fails, check column names with get_columns. If table is not found, discover available tables with get_tables. If timeout occurs, simplify the query (fewer rows, fewer columns) or reduce limit parameter.' Implement this in code by returning structured error responses with recovery hints.
Add tool annotations. Set readOnlyHint=true for all three tools (they never modify state). This signals to clients and LLMs that these are safe for read-only scenarios.
Add input validation in tool implementations. Validate that sql parameter starts with SELECT (case-insensitive). Validate that table and column names are valid identifiers (alphanumeric + underscore). Return clear error messages with the invalid value and constraint violated, e.g., 'Invalid SQL: must be a SELECT statement, got: INSERT INTO...'
Consider adding a 'summary' variant (get_tables_summary, get_columns_summary) that returns just count of tables/columns, or add a 'include_metadata' boolean parameter to reduce default output verbosity.