Skip to main content
Glama
nolleh
by nolleh

execute_query

Execute SQL queries on Vertica databases to retrieve and analyze data through the MCP Vertica server's connection management and security features.

Instructions

Execute a SQL query and return the results.

Args:
    ctx: FastMCP context for progress reporting and logging
    query: SQL query to execute
    database: Optional database name to execute the query against

Returns:
    Query results as a string

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes

Implementation Reference

  • The primary handler for the 'execute_query' MCP tool. Decorated with @mcp.tool() for automatic registration. Executes SQL queries on Vertica, manages connections, checks schema permissions based on operation type, fetches results, and returns them as a string.
    @mcp.tool()
    async def execute_query(ctx: Context, query: str) -> str:
        """Execute a SQL query and return the results.
    
        Args:
            ctx: FastMCP context for progress reporting and logging
            query: SQL query to execute
            database: Optional database name to execute the query against
    
        Returns:
            Query results as a string
        """
        await ctx.info(f"Executing query: {query}")
    
        # Get or create connection manager
        manager = await get_or_create_manager(ctx)
        if not manager:
            return "Error: Failed to initialize database connection. Check configuration."
    
        # Extract schema from query if not provided
        schema = extract_schema_from_query(query)
        # Check operation permissions
        operation = extract_operation_type(query)
        if operation and not manager.is_operation_allowed(schema or "default", operation):
            error_msg = f"Operation {operation.name} not allowed for schema {schema}"
            await ctx.error(error_msg)
            return error_msg
    
        conn = None
        cursor = None
        try:
            conn = manager.get_connection()  # Always use default DB connection
            cursor = conn.cursor()
            cursor.execute(query)
            results = cursor.fetchall()
            await ctx.info(f"Query executed successfully, returned {len(results)} rows")
            return str(results)
        except Exception as e:
            error_msg = f"Error executing query: {str(e)}"
            await ctx.error(error_msg)
            return error_msg
        finally:
            if cursor:
                cursor.close()
            if conn:
                manager.release_connection(conn)
  • Helper function used by execute_query to lazily obtain or create the VerticaConnectionManager from the MCP context.
    async def get_or_create_manager(ctx: Context) -> VerticaConnectionManager | None:
        """Get connection manager from context or create it lazily.
    
        Args:
            ctx: FastMCP context
    
        Returns:
            VerticaConnectionManager instance or None if creation fails
        """
        manager = ctx.request_context.lifespan_context.get("vertica_manager")
        if not manager:
            try:
                manager = VerticaConnectionManager()
                config = VerticaConfig.from_env()
                manager.initialize_default(config)
                await ctx.info("Connection manager initialized from request config")
            except Exception as e:
                await ctx.error(f"Failed to initialize database connection: {str(e)}")
                return None
        return manager
  • Helper to determine the SQL operation type (e.g., INSERT, DDL) for permission checks in execute_query.
    def extract_operation_type(query: str) -> OperationType | None:
        """Extract the operation type from a SQL query."""
        query = query.strip().upper()
    
        if query.startswith("INSERT"):
            return OperationType.INSERT
        elif query.startswith("UPDATE"):
            return OperationType.UPDATE
        elif query.startswith("DELETE"):
            return OperationType.DELETE
        elif any(query.startswith(op) for op in ["CREATE", "ALTER", "DROP", "TRUNCATE"]):
            return OperationType.DDL
        return None
  • Helper to extract schema name from SQL query for permission validation in execute_query.
    def extract_schema_from_query(query: str) -> str | None:
        """Extract schema name from a SQL query."""
        # database.table 또는 schema.table 패턴에서 schema 추출
        match = re.search(r"([a-zA-Z0-9_]+)\.[a-zA-Z0-9_]+", query)
        if match:
            return match.group(1)
        return None
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the tool executes SQL queries and returns results as a string, but lacks critical details: whether it's read-only or can modify data, authentication requirements, error handling, performance implications (e.g., timeouts), or rate limits. For a tool with potential data mutation risks, this is a significant gap.

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

Conciseness4/5

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

The description is well-structured and appropriately sized. It front-loads the core purpose in the first sentence, followed by clear sections for Args and Returns. There's minimal redundancy, though the mention of 'ctx' (not in the schema) and 'database' (optional but schema-lacking) could be streamlined.

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?

Given the complexity of SQL execution (potential for data mutation, errors, performance issues) and the absence of both annotations and an output schema, the description is insufficient. It doesn't address safety, permissions, result formatting beyond 'string', or how to handle large results. For a tool with such critical behavioral aspects, more context is needed.

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

Parameters3/5

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

The description adds some semantic context beyond the input schema. The schema only documents 'query' as a required string parameter. The description clarifies that 'query' is a 'SQL query to execute' and mentions an optional 'database' parameter (though this isn't in the schema, which may indicate inconsistency). With 0% schema description coverage, the description provides basic but incomplete parameter semantics.

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 tool's purpose: 'Execute a SQL query and return the results.' It specifies the verb ('execute') and resource ('SQL query'), making the function unambiguous. However, it doesn't explicitly differentiate from sibling tools like stream_query or get_table_structure, which prevents a perfect score.

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 like stream_query or list_views. It mentions an optional 'database' parameter in the Args section, but this doesn't constitute usage guidelines. Without any context on appropriate scenarios or exclusions, the agent lacks direction.

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/nolleh/mcp-vertica'

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