query-data
Execute Flux queries against InfluxDB to inspect measurement schemas, run aggregations, or validate recently written data within an organization.
Instructions
Execute a Flux query inside an organization to inspect measurement schemas, run aggregations, or validate recently written data.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| org | Yes | Organization whose buckets the query should target (exact name, not ID). | |
| query | Yes | Flux query text. Multi-line strings are supported; results are returned as annotated CSV for easy parsing. |
Implementation Reference
- src/handlers/queryDataTool.js:4-31 (handler)The handler function that executes the tool logic. It takes { org, query }, makes a POST request to InfluxDB's /api/v2/query endpoint with a Flux query, and returns the response text (annotated CSV) as content.
export async function queryData({ org, query }) { try { const response = await influxRequest( `/api/v2/query?org=${encodeURIComponent(org)}`, { method: "POST", body: JSON.stringify({ query, type: "flux" }), }, ); const responseText = await response.text(); return { content: [{ type: "text", text: responseText, }], }; } catch (error) { return { content: [{ type: "text", text: `Error executing query: ${error.message}`, }], isError: true, }; } } - src/index.js:103-119 (registration)Registration of the 'query-data' tool via server.tool(). Defines the tool name, description, input schema (org and query strings), and binds the queryData handler.
server.tool( "query-data", "Execute a Flux query inside an organization to inspect measurement schemas, run aggregations, or validate recently written data.", { org: z .string() .describe( "Organization whose buckets the query should target (exact name, not ID).", ), query: z .string() .describe( "Flux query text. Multi-line strings are supported; results are returned as annotated CSV for easy parsing.", ), }, queryData, ); - src/utils/influxClient.js:5-69 (helper)The influxRequest helper used by queryData to make authenticated HTTP requests to the InfluxDB API with timeout and error handling.
export async function influxRequest(endpoint, options = {}, timeoutMs = 5000) { const url = `${INFLUXDB_URL}${endpoint}`; const defaultOptions = { headers: { Authorization: `Token ${INFLUXDB_TOKEN}`, "Content-Type": "application/json", }, }; console.log(`Making request to: ${url}`); try { // Use AbortController for proper request cancellation const controller = new AbortController(); const timeoutId = setTimeout(() => { controller.abort(`InfluxDB API request timed out after ${timeoutMs}ms`); }, timeoutMs); // Properly merge headers to avoid conflicts // This ensures custom headers (like Content-Type) aren't overridden const mergedHeaders = { ...defaultOptions.headers, ...options.headers || {}, }; // Add the abort signal to the request options const requestOptions = { ...defaultOptions, ...options, headers: mergedHeaders, signal: controller.signal, }; console.log(`Request options: ${JSON.stringify({ method: requestOptions.method, headers: Object.keys(requestOptions.headers), }) }`); // Make the request const response = await fetch(url, requestOptions); // Clear the timeout since the request completed clearTimeout(timeoutId); console.log(`Response status: ${response.status}`); if (!response.ok) { const errorText = await Promise.race([ response.text(), new Promise((_, reject) => setTimeout(() => reject(new Error("Response text timeout")), 3000) ), ]); throw new Error(`InfluxDB API Error (${response.status}): ${errorText}`); } return response; } catch (error) { // Log the error with more details console.error(`Error in influxRequest to ${url}:`, error.message); // Rethrow to be handled by the caller throw error; } } - src/index.js:107-117 (schema)Input schema for the 'query-data' tool: 'org' (string) and 'query' (string) parameters, validated with Zod.
org: z .string() .describe( "Organization whose buckets the query should target (exact name, not ID).", ), query: z .string() .describe( "Flux query text. Multi-line strings are supported; results are returned as annotated CSV for easy parsing.", ), },