Files
mesh-catalog/modules/grafana/tools/index.ts

56 lines
2.0 KiB
TypeScript

// grafana's tools — moved here from the shared hal sdk (novox/hq ADR 0039), importing grafana's own
// client. They return structured data; the mesh serves them through the sdk's tool harness.
import { registerModuleTools, type ToolDefinition } from "@novox/mesh-sdk/tools";
import { GrafanaClient } from "../client.js";
export function getGrafanaTools(grafana: GrafanaClient): ToolDefinition[] {
return [
{
name: "grafana_status",
description: "Grafana server health — database state, version, build commit.",
input: {},
run: async () => grafana.health(),
},
{
name: "grafana_list_datasources",
description: "List Grafana data sources — name, type, backing URL, which is default.",
input: {},
run: async () => {
const datasources = await grafana.listDatasources();
return { count: datasources.length, datasources };
},
},
{
name: "grafana_list_dashboards",
description: "List Grafana dashboards, optionally filtered by a name query.",
input: { query: { type: "string", description: "filter dashboards by name (optional)" } },
run: async (args) => {
const query = args.query ? String(args.query) : undefined;
const dashboards = await grafana.listDashboards(query);
return { count: dashboards.length, dashboards };
},
},
{
name: "grafana_alerts",
description: "Active Grafana alert instances and their state (Alerting, Pending, Normal).",
input: {},
run: async () => {
const alerts = await grafana.listAlerts();
const firing = alerts.filter((a) => a.state.toLowerCase() === "alerting");
return { count: alerts.length, firing: firing.length, alerts };
},
},
];
}
// The tools exist only when Grafana auth can be resolved; without it, grafana contributes none
// rather than failing the whole tool runtime.
registerModuleTools("grafana", (env) => {
try {
return getGrafanaTools(GrafanaClient.fromEnv(env));
} catch {
return [];
}
});