Skip to main content
Glama
jasonsmithj

Redash MCP Server

by jasonsmithj

execute_query_and_wait

Execute SQL queries on Redash data sources and wait for results, supporting cached results with configurable maximum age.

Instructions

Execute a SQL query and wait for the result

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesThe SQL query to execute
data_source_idYesThe ID of the data source to query
max_ageNoMaximum age of cached results in seconds

Implementation Reference

  • Handler function that validates input parameters, constructs the query execution request, calls the Redash client's executeQueryAndWait method, and returns the result as formatted JSON or an error message.
    handler: async (args, client) => {
      try {
        const { query, data_source_id, max_age } = args;
    
        if (typeof query !== 'string') {
          return {
            content: [
              {
                type: 'text',
                text: 'Error: query is required and must be a string',
              } as TextContent,
            ],
            isError: true,
          };
        }
    
        if (typeof data_source_id !== 'number') {
          return {
            content: [
              {
                type: 'text',
                text: 'Error: data_source_id is required and must be a number',
              } as TextContent,
            ],
            isError: true,
          };
        }
    
        const request = {
          query,
          data_source_id,
          ...(typeof max_age === 'number' ? { max_age } : {}),
        };
    
        const result = await client.executeQueryAndWait(request);
    
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(result, null, 2),
            } as TextContent,
          ],
        };
      } catch (error) {
        return {
          content: [
            {
              type: 'text',
              text: `Error executing query: ${error instanceof Error ? error.message : String(error)}`,
            } as TextContent,
          ],
          isError: true,
        };
      }
    },
  • Input schema defining the parameters for the tool: required 'query' (string) and 'data_source_id' (number), optional 'max_age' (number).
    inputSchema: {
      type: 'object',
      properties: {
        query: {
          type: 'string',
          description: 'The SQL query to execute',
          minLength: 1,
        },
        data_source_id: {
          type: 'number',
          description: 'The ID of the data source to query',
          minimum: 1,
        },
        max_age: {
          type: 'number',
          description: 'Maximum age of cached results in seconds',
          minimum: 0,
        },
      },
      required: ['query', 'data_source_id'],
      additionalProperties: false,
    },
  • src/index.ts:59-59 (registration)
    Registration of the executeQueryAndWaitTool in the central tools array used for list_tools and call_tool request handling.
    const tools = [listDataSourcesTool, getDataSourceTool, executeQueryAndWaitTool, listQueriesTool];
  • src/index.ts:17-17 (registration)
    Import statement bringing the executeQueryAndWaitTool into the main index file for registration.
    import { executeQueryAndWaitTool, listQueriesTool } from './tools/query.js';
  • Supporting method in RedashClient that executes the query via API, handles cached results or polls the job status until completion or failure/timeout.
    async executeQueryAndWait(
      request: QueryExecutionRequest,
      pollInterval = 1000,
      maxAttempts = 60
    ): Promise<QueryResult> {
      // Execute query
      const response = await this.executeQuery(request);
    
      // Check if we got a cached result directly
      if ('query_result' in response) {
        return (response as unknown as { query_result: QueryResult }).query_result;
      }
    
      // Otherwise, poll for job completion
      const { job } = response;
      if (!job) {
        throw new Error('Invalid response: neither job nor query_result found');
      }
    
      // Poll for completion
      let attempts = 0;
      while (attempts < maxAttempts) {
        const { job: currentJob } = await this.getJob(job.id);
    
        // Status: 3 = success
        if (currentJob.status === 3) {
          if (!currentJob.query_result_id) {
            throw new Error('Query completed but no result ID found');
          }
          return this.getQueryResult(currentJob.query_result_id);
        }
    
        // Status: 4 = failure
        if (currentJob.status === 4) {
          const error: RedashApiError = {
            message: currentJob.error ?? 'Query execution failed',
            job: currentJob,
          };
          throw error;
        }
    
        // Wait before polling again
        await new Promise((resolve) => setTimeout(resolve, pollInterval));
        attempts++;
      }
    
      throw new Error(`Query execution timeout after ${maxAttempts} attempts`);
    }
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions waiting for the result, which implies synchronous behavior, but fails to cover critical aspects like permissions needed, rate limits, error handling, or whether the query can be destructive (e.g., UPDATE/DELETE). This leaves significant gaps for a tool that executes SQL queries.

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 a single, efficient sentence that directly states the tool's function without unnecessary words. It is front-loaded and appropriately sized, making it easy to understand at a glance.

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 executing SQL queries, the lack of annotations, and no output schema, the description is incomplete. It does not address behavioral traits like safety, performance, or result format, leaving the agent with insufficient context for reliable tool invocation.

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?

Schema description coverage is 100%, so the schema already documents all three parameters (query, data_source_id, max_age) with clear descriptions. The description adds no additional meaning beyond what the schema provides, such as query syntax examples or data source context, meeting the baseline for high schema coverage.

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 verb ('execute') and resource ('SQL query'), specifying that it waits for the result, which distinguishes it from potential async variants. However, it does not explicitly differentiate from sibling tools like list_queries, which might also involve queries but for listing rather than execution.

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?

No guidance is provided on when to use this tool versus alternatives, such as whether to use it for read-only queries or if there are async options. The description lacks context on prerequisites, exclusions, or comparisons to siblings like get_data_source or list_data_sources.

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/jasonsmithj/redash-mcp'

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