openclaw-grafana-lens
Version:
OpenClaw plugin that gives AI agents full Grafana access — 18 composable tools for PromQL/LogQL/TraceQL queries, dashboard creation, alerting, SRE investigation, security monitoring, data collection pipeline management via Grafana Alloy (29 recipes), and
70 lines (69 loc) • 3.16 kB
JavaScript
/**
* grafana_explore_datasources tool
*
* Discovers what datasources are configured in Grafana. This is the
* agent's starting point for understanding what data is available —
* it provides the datasource UIDs needed by grafana_query and
* grafana_list_metrics, plus routing hints for which tool to use.
*/
import { jsonResult, readStringParam } from "../sdk-compat.js";
import { instanceProperties } from "./instance-param.js";
/** Maps datasource type → agent tool routing info. */
const DATASOURCE_CAPABILITIES = {
prometheus: { queryTool: "grafana_query", queryLanguage: "PromQL" },
loki: { queryTool: "grafana_query_logs", queryLanguage: "LogQL" },
tempo: { queryTool: "grafana_query_traces", queryLanguage: "TraceQL" },
};
/** Returns routing hints for a datasource type, or an unsupported fallback. */
export function getQueryCapability(dsType) {
const cap = DATASOURCE_CAPABILITIES[dsType];
if (cap)
return { ...cap, supported: true };
return { queryTool: null, queryLanguage: null, supported: false };
}
export function createExploreDatasourcesToolFactory(registry) {
return (_ctx) => ({
name: "grafana_explore_datasources",
label: "Explore Datasources",
description: [
"Discover datasources configured in Grafana.",
"WORKFLOW: Use first to find datasource UIDs needed by grafana_query, grafana_query_logs, grafana_query_traces, grafana_list_metrics, grafana_create_alert, and grafana_explain_metric.",
"Returns datasources with UIDs, types, and queryTool routing (which tool + query language to use for each datasource).",
"No parameters required.",
].join(" "),
parameters: {
type: "object",
properties: {
...instanceProperties(registry),
},
},
async execute(_toolCallId, _params) {
const instanceName = readStringParam(_params, "instance");
const client = registry.get(instanceName);
try {
const datasources = await client.listDatasources();
const result = {
status: "success",
count: datasources.length,
datasources: datasources.map((ds) => ({
uid: ds.uid,
name: ds.name,
type: ds.type,
isDefault: ds.isDefault,
...getQueryCapability(ds.type),
})),
};
// Multi-instance: include instance context so the agent knows what's available
if (registry.isMultiInstance()) {
result.instance = instanceName ?? registry.getDefaultName();
result.availableInstances = registry.listInstances();
}
return jsonResult(result);
}
catch (err) {
const reason = err instanceof Error ? err.message : String(err);
return jsonResult({ error: `Failed to list datasources: ${reason}` });
}
},
});
}