MCP server for SkySQL database management, providing tools to list DB agents, launch serverless databases, delete databases, query agents, and execute SQL commands
Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
The SkySQL MCP server provides 4 tools with verb-based naming (list_agents, launch_serverless_db, delete_db, ask_agent) and mostly complete schemas. However, several definition quality gaps reduce the score. All tools have descriptions (10-50 chars range, mostly adequate), and input schemas are present with type definitions. The server demonstrates good HTTP transport and tool annotation usage. Key gaps: parameter descriptions are minimal or missing for several inputs (e.g., 'region' and 'provider' in launch_serverless_db lack constraint detail), output schemas are not formally documented in tool definitions, and error handling guidance is absent. The code shows proper async handling, logging, and API key security via header injection, but tool composition could be improved, launch_serverless_db and delete_db are destructive operations that should include dry-run or confirmation patterns.
launch_serverless_db lacks parameter constraint descriptions. 'region' defaults to 'eastus' but does not document valid values or format. 'provider' defaults to 'azure' but does not enumerate all valid providers (Azure, AWS, GCP?). LLMs cannot validate inputs without explicit constraints.
Output schemas are not formally documented in tool definitions. Tools return LlamaResponse, AgentInfo, and ServerlessDBResponse Pydantic models in code, but these structures are not exposed in the MCP tool registration. LLMs cannot plan downstream calls without knowing what fields to expect.
Destructive operations (launch_serverless_db, delete_db) lack confirmation or dry-run support. Agents can irreversibly destroy cloud resources without a second validation step. No confirmation_request or dry-run pattern implemented.
launch_serverless_dbdelete_db
Recommendations
Add explicit enum or constraint documentation for 'region' and 'provider' parameters in launch_serverless_db. Example: 'region: Cloud region (eastus, westus, northeu, southafricanorth, etc.), defaults to eastus' and 'provider: Cloud provider (azure|aws|gcp), defaults to azure'.
Document all output schemas as JSON Schema in the tool definitions. For each tool, add a 'returns' field describing the structure. Example for list_agents: 'Returns an array of agent objects, each with {id: string, name: string, description: string, type: string, status: string, datasource_id: string}'.
Implement a confirm_delete_db tool or a dry_run parameter for delete_db. Agents should preview what will be deleted before irreversibly destroying it. Example: 'dry_run=true returns a summary of the service to be deleted; dry_run=false executes the deletion.'
Enhance error responses with recovery guidance. Wrap API calls in try-except blocks that return structured errors. Example: 'Agent not found. Try calling list_agents() first to retrieve valid agent IDs.' or 'Region 'eastus2' not supported. Available regions: eastus, westus, northeu, southafricanorth.'
Add a 'service_id' parameter description to delete_db: 'The ID of the database service to delete. Use the service_id field from launch_serverless_db response or list from describe_services(). This operation is irreversible.'
Implement permission checks in launch_serverless_db and delete_db. Before executing, verify the caller's SkySQL API key has 'write:database' scope. Return a 403 Forbidden with 'Insufficient permissions. Your API key lacks write:database scope.' if not authorized.
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Error handling provides no recovery guidance. The code calls response.raise_for_status() and returns generic exceptions. LLMs receive no actionable next steps (e.g., 'Try search_agents() if the agent_id is invalid' or 'Rate limited, retry in 30 seconds').
Parameter 'service_id' in delete_db is not described. No guidance on format, where to obtain it, or what happens if an invalid ID is provided. LLMs have no way to resolve a service name to a service_id.
No permission checks or scope declarations. Tools like delete_db and launch_serverless_db modify cloud infrastructure but do not verify caller authorization. Code resolves API keys but does not gate destructive operations behind RBAC or permission validation.
Tool responses from ask_agent (LlamaResponse with 'content', 'sql_text', 'error_text', 'col_keys') are structured but not documented in the tool definition. LLMs cannot plan how to present results to users (e.g., whether to display SQL or just content).
list_agents returns all agents without pagination or limit enforcement. The code caches agents but does not document whether results are truncated, what the maximum result count is, or how to retrieve additional pages if the agent list is large.
list_agents
Add scope declarations to each tool (as tool annotations or a capabilities field). Example: list_agents requires 'read:agents', launch_serverless_db requires 'write:database|create:database', delete_db requires 'write:database|delete:database'.
Document the ask_agent response structure: 'Returns {content: string (the agent's answer), sql_text: string (the SQL query executed, if any), error_text: string (any errors encountered), col_keys: [string] (column names in the result set)}'.
Add pagination support to list_agents. Document the maximum result count (e.g., '100 agents max per call'). If the result count reaches the limit, include a 'next_cursor' field in the response so the agent can fetch additional pages.
Add 'readOnlyHint: true' and 'idempotentHint: true' annotations to list_agents and ask_agent to signal they are safe to call repeatedly. add 'destructiveHint: true' to launch_serverless_db and delete_db to signal irreversible side effects.
Consider adding a describe_services() or get_service_status() tool so agents can map a friendly database name to a service_id before calling delete_db. This improves the natural-identifier pattern, users think in names, not IDs.
Add timeout and rate-limit handling. Document that API calls timeout after 30s (already set in code). Return actionable guidance: 'Service creation timed out. The database may still be launching in the background. Call get_service_status() to check.'
Log all tool invocations with the caller's API key hash (already done via _cache_key), operation, parameters, and result. This creates an audit trail for compliance and incident response.