This server exposes database credentials as tool parameters, which is a critical security violation. Descriptions are minimal (10-40 chars), below the 50-200 char baseline for LLM-optimized tooling. Schemas are present and properly typed, but parameters lack descriptions in several cases. Tool names follow verb_noun convention adequately. The server requires per-request credentials (ip, user, password) for every call, forcing repetition and leaking secrets into logs. No input validation, error guidance, or recovery instructions beyond generic failure messages. Notably, write protection relies on naive regex matching rather than proper statement parsing.
Credentials exposed as tool parameters (ip, user, password, port, database). These appear in every tool call and are logged in agent traces, violating secret-injection pattern.
Tool descriptions are extremely brief (10-25 chars), far below the 50-200 char LLM-optimized baseline. 'Query table structure' and '查询视图定义' lack context for when/why to use each tool and what they return.
Many parameters lack descriptions. 'port', 'database', 'user', 'password', 'ip' appear across all tools with minimal or no guidance on format, constraints, or why they are required.
Move database credentials to server-side configuration (environment variables, config file, or vault integration). Accept only a connection_name or connection_id parameter. This eliminates secret leakage in logs and traces.
Expand all tool descriptions to 50-150 characters. For example: 'query' → 'Execute SQL SELECT queries to retrieve data. Cannot execute INSERT, UPDATE, DELETE, or DDL statements. Returns rows as JSON objects.' Add WHEN to use each tool: 'get_table_structure → Call this first to understand column names and types before writing queries.'
Add descriptions to all parameters. Example for 'port': 'MSSQL server port (default: 1433). Valid range: 1 - 65535.'
Document output schema for each tool. For 'query': 'Returns { success: boolean, rows: Array<Record<string, any>>, rowCount: number, duration_ms: number }. Each row is a key-value object where keys are column names.'
Implement proper SQL parsing (e.g., use a SQL parser library like sql-parser-js) to validate statements instead of regex. Or move write-protection to the database user permissions layer (grant SELECT only).
Add error recovery guidance. Example: 'Connection failed: Could not connect to 192.168.1.1:1433. Check network, IP address, port, and credentials.' Or 'Column name not found: "user_id". Available columns: id, username, email, created_at.'
Add per-tool help text: 'Use get_table_structure to explore schema before running queries. Use get_procedure_content to review stored procedure logic. Use get_view_definition to understand view composition.'
Write operation blocking uses naive regex matching (/\b(INSERT|UPDATE|DELETE...)\b/i) which is bypassable and not a robust SQL parser. Multi-statement payloads, comments, and encoding tricks can circumvent the check.
No error recovery guidance. Error messages like 'Connection failed' or 'Query executed' do not tell the LLM what to do next: retry, adjust parameters, ask the user, or give up.
No input validation or constraint documentation. Parameters like 'port' accept any number (should be 0-65535). 'database' and 'user' accept empty strings. Descriptions do not specify required format or allowed values.
'query' description toggles based on ENABLE_WRITE flag, but the tool is identical. This creates confusion: an LLM may see conflicting descriptions in logs or between invocations if the flag changes.
query
Validate numeric parameters (port 1 - 65535), non-empty strings (database, user), and IP format.
Return structured, paginated results. For 'query' returning large result sets, cap at 100 rows and return { success, rows, totalRowCount, hasMore, nextOffset }.
Add an optional 'connection_name' parameter (or use server config) to allow pre-configured connections. This reduces parameter clutter and eliminates per-request credential exposure.
Document which errors are retryable (network timeout → retry; invalid SQL → do not retry) so the LLM self-corrects appropriately.