Skip to main content
Glama
ydb-platform

YDB MCP

Official
by ydb-platform

ydb_query

Execute SQL queries on YDB databases to retrieve, analyze, or modify data through structured database operations.

Instructions

Run a SQL query against YDB database

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sqlYes
paramsNo

Implementation Reference

  • Core handler function that executes the ydb_query tool: runs SQL against YDB, handles optional parameters, processes multiple result sets, formats output as JSON TextContent.
    async def query(self, sql: str, params: Optional[Dict[str, Any]] = None) -> List[TextContent]:
        """Run a SQL query against YDB.
    
        Args:
            sql: SQL query to execute
            params: Optional query parameters
    
        Returns:
            List of TextContent objects with JSON-formatted results
        """
        # Check if there's an authentication error
        if self.auth_error:
            return [TextContent(type="text", text=json.dumps({"error": self.auth_error}, indent=2))]
    
        try:
            pool = await self.get_pool()
            ydb_params = None
            if params:
                ydb_params = {}
                for key, value in params.items():
                    param_key = key if key.startswith("$") else f"${key}"
                    ydb_params[param_key] = value
            result_sets = await pool.execute_with_retries(sql, ydb_params)
            all_results = []
            for result_set in result_sets:
                processed = self._process_result_set(result_set)
                all_results.append(processed)
            # Convert all dict keys to strings for JSON serialization
            safe_result = self._stringify_dict_keys({"result_sets": all_results})
            return [TextContent(type="text", text=json.dumps(safe_result, indent=2, cls=CustomJSONEncoder))]
        except Exception as e:
            error_message = str(e)
            safe_error = self._stringify_dict_keys({"error": error_message})
            return [TextContent(type="text", text=json.dumps(safe_error, indent=2))]
  • Tool registration specification for ydb_query, defining name, description, handler (self.query), and input parameters schema.
    {
        "name": "ydb_query",
        "description": "Run a SQL query against YDB database",
        "handler": self.query,  # Use real handler
        "parameters": {
            "properties": {"sql": {"type": "string", "title": "Sql"}},
            "required": ["sql"],
            "type": "object",
        },
    },
  • JSON schema defining the input parameters for the ydb_query tool: requires 'sql' string.
    "parameters": {
        "properties": {"sql": {"type": "string", "title": "Sql"}},
        "required": ["sql"],
        "type": "object",
    },
  • Helper function used by the query handler to process YDB result sets into structured dictionaries with columns and rows.
    def _process_result_set(self, result_set):
        """Process YDB result set into a dictionary format.
    
        Args:
            result_set: YDB result set object
    
        Returns:
            Processed result set as a dictionary
        """
        try:
            # Extract columns
            columns = []
            try:
                # Get column names from the columns attribute
                columns_attr = getattr(result_set, "columns")
                columns = [col.name for col in columns_attr]
            except Exception as e:
                logger.exception(f"Error getting columns: {e}")
                return {"error": str(e), "columns": [], "rows": []}
    
            # Extract rows
            rows = []
            try:
                rows_attr = getattr(result_set, "rows")
                for row in rows_attr:
                    row_values = []
                    for i in range(len(columns)):
                        row_values.append(row[i])
                    rows.append(row_values)
            except Exception as e:
                logger.exception(f"Error getting rows: {e}")
                return {"error": str(e), "columns": columns, "rows": []}
    
            return {"columns": columns, "rows": rows}
        except Exception as e:
            logger.exception(f"Error processing result set: {e}")
            return {"error": str(e), "columns": [], "rows": []}
  • Dispatch logic in call_tool method that invokes the ydb_query handler when the tool is called.
    if tool_name == "ydb_query" and "sql" in params:
        result = await self.query(sql=params["sql"])
    elif tool_name == "ydb_query_with_params" and "sql" in params and "params" in params:
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden for behavioral disclosure. While 'Run a SQL query' implies a read/write operation, the description doesn't specify whether this executes SELECT queries only, supports DML/DDL, requires specific permissions, has transaction implications, or provides result formatting. For a database query tool with zero annotation coverage, this leaves significant behavioral questions unanswered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise at just 7 words, front-loading the core functionality with zero wasted words. Every element ('Run', 'SQL query', 'against YDB database') earns its place by conveying essential information efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a database query execution tool with 2 parameters, no annotations, and no output schema, the description is insufficiently complete. It doesn't address critical context like query types supported, result format, error handling, performance considerations, or how it differs from parameterized sibling tools. The minimal description leaves too many operational questions unanswered.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage for both parameters, the description provides no information about the 'sql' parameter (query syntax, supported SQL dialect, size limits) or 'params' parameter (parameter binding format, supported data types). The description doesn't compensate for the complete lack of schema documentation, leaving both parameters semantically undefined.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Run a SQL query') and target resource ('against YDB database'), providing a specific verb+resource combination. However, it doesn't distinguish this tool from its sibling 'ydb_query_with_params', which appears to serve a similar purpose with parameter support.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. With multiple sibling tools including 'ydb_query_with_params', 'ydb_explain_query', and 'ydb_explain_query_with_params', there's no indication of when this specific query execution tool is appropriate versus when to use parameterized versions or explain tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ydb-platform/ydb-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server