github grafana/mcp-grafana v1.2.0

3 hours ago

Added

  • alerting_manage_silences tool (opt-in, read/write-gated) to list, create, and expire Grafana alert silences (#991)
  • update_incident tool to update fields on an existing incident (#1080)
  • update_alert_group tool to acknowledge and resolve Grafana OnCall alert groups (#1083)
  • get_alert_group now returns the last alert payload for the group, so callers can inspect the triggering alert without a second lookup (#1081)
  • Agent Observability agento11y_manage_experiments and agento11y_manage_test_suites tools, in the opt-in agento11y category (#1062)
  • Compact output format for query_loki_logs, reducing token usage for large log result sets (#990)
  • Opt-in Loki query cost guardrail for query_loki_logs (--loki-guardrail-mode / GRAFANA_LOKI_GUARDRAIL_MODE, off by default, with shadow and enforce modes). Because Loki query cost is bytes scanned — determined only by the stream selector and time range, not line filters — the guardrail requires a selective stream selector, caps the time range (--loki-guardrail-max-range, default 24h), and pre-checks Loki's index/stats byte estimate against a budget (--loki-guardrail-max-bytes, default 100GiB). Blocked queries return an MCP tool error with rewrite guidance; unparseable queries fail open (#1031)
  • OpenTelemetry counters recording Loki cost-guardrail decisions (allowed, blocked, failed-open), so operators can observe the guardrail's impact (#1095)
  • run_panel_query now supports PostgreSQL (#1112) and MSSQL (#1042) datasources
  • Datasource resolution falls back to /api/frontend/settings when the datasource metadata API is forbidden, so tools keep working on instances that restrict it (#1015)
  • GrafanaVersion(ctx) exposes the targeted Grafana version to tools, so they can gate behaviour on it instead of inferring capability from API versions (#1091)
  • Optional orgId parameter on get_panel_image to render a panel for a specific organisation (#903)
  • list_datasources now supports filtering by name (#973)
  • --server-name flag (and GRAFANA_MCP_SERVER_NAME env var) to set a custom MCP server name in the handshake and OTel service.name, so operators can distinguish multiple instances (#1011)
  • Scoped SOCKS5 egress proxy via GRAFANA_SOCKS5_PROXY, routing outbound Grafana traffic through a SOCKS5 proxy (#1119)
  • An MCP Bundle (.mcpb) for Claude Desktop is now built and attached on release (#1077)

Changed

  • Bumped mcp-go from v0.55.0 to v0.58.0, picking up fixes for tool-filter scans on the tools/call hot path, raw JSON preservation for tool arguments and structuredContent, schema tags on nested fields, multi-line SSE data fields, and HEAD requests returning 200. This also inherits mcp-go's new default-on DNS rebinding protection, which returns 403 when a request arrives over a loopback connection with a non-loopback Host header — a second check underneath DNSRebindingProtectionMiddleware that --allowed-hosts cannot loosen. Default deployments are unaffected, since DefaultAllowedHosts already restricts Host to loopback variants; operators who widen --allowed-hosts while a same-host reverse proxy forwards over loopback preserving a non-localhost Host should configure the proxy to rewrite Host to localhost (#1097)
  • tools.Stats.Bytes is now int64 (was int) so index/stats byte counts cannot overflow on 32-bit platforms; Go API consumers of the exported struct may need a cast (#1031)
  • /api/frontend/settings is now fetched once per Grafana instance instead of up to three times. The public URL, the Grafana version and the dashboard namespace previously each fetched that endpoint behind a cache of their own, even though a single response carries all three fields. mcpgrafana.GrafanaClient gains a Version field populated by the same request that populates PublicURL, and mcpgrafana.GrafanaVersion prefers it, so a tool holding a client reads the version with no HTTP request at all — previously it cost a blocking round trip on a detached context the caller could not cancel. The namespace keeps a separate org-keyed cache, because Grafana computes it for the requesting org and a URL-keyed entry would serve one org another org's namespace. Failed fetches are still retried rather than cached, but a successful fetch that simply omits buildInfo is now cached instead of being refetched on every call (#1115)

Fixed

  • Closed two gaps in the GRAFANA_SOCKS5_PROXY egress guarantee. The install_plugin and search_plugin_information tools reached the grafana.com plugin catalog via http.DefaultClient, bypassing the configured SOCKS5 proxy entirely; these requests now route through the proxy (carrying no Grafana credentials or forwarded headers) and fail closed when it is misconfigured. NewGrafanaClient now installs a fail-closed transport instead of panicking when the proxy cannot be applied, matching the OnCall and incident paths, and the per-call fail-closed logic is centralised in one helper (#1121)
  • observability.ToolMetricDimensions now bounds the mcp.tool.phase metric label against the toolMetricDims allowlist, like mcp.tool.operation and mcp.tool.resource_type. Phase is read from a tool result's _meta, and results proxied from an MCP-enabled datasource come from a remote server rather than from this repo, so the label was unbounded-cardinality in the general case. A tool that does not opt into phases now contributes no phase, and an opted-in tool reporting an unexpected value reports other. Behaviour is unchanged for every in-tree tool: create_datasource is the only producer, with schema and created (#1094)
  • Distributed traces are no longer broken over the HTTP transports: the server now installs a global OTel TextMapPropagator (via autoprop, honouring OTEL_PROPAGATORS, default tracecontext,baggage), so an inbound traceparent continues the caller's trace and outbound Grafana API requests carry one of their own. Previously every hop started a disconnected trace. Trace context forwarded via GRAFANA_FORWARD_HEADERS no longer overrides the propagated value, which would have cut mcp-grafana out of the middle of the trace (#1084)
  • Grafana-managed alert rule UIDs are recovered from the internal __alert_rule_uid__ / __alert_rule_namespace_uid__ labels when older Grafana responses omit the top-level UID fields; those internal labels are stripped from the returned summary so they don't surface as user labels (#968)
  • Alert rule matchers are now encoded in the JSON shape Grafana expects, fixing rule create/update requests that Grafana previously rejected (#1111)
  • run_panel_query now resolves constant and textbox dashboard variables from their query field, so panels using them return correct results (#1041)
  • Datasource queries fall back to the legacy proxy on a 401, restoring queries against datasources the metadata proxy rejects (#1022)
  • URL shortening for navigation deeplinks now sends a relative path, fixing link generation on some deployments (#974)
  • GRAFANA_URL is normalized where it enters the process (trailing slash trimmed, missing scheme supplied), so the config, API client, and client-cache key all agree on the target. Previously a schemeless value such as 127.0.0.1:3000 could panic at startup or produce hostless requests (#1034)
  • Proxied tools auto-wire SetToolManager and report a clearer error when the tool manager is nil (#1102)
  • The session wait when building a proxied tool set is now bounded, so a slow or unavailable datasource can no longer hang tool discovery (#1087)
  • Transient proxied-tool discovery/connect failures are retried and connections are established in parallel, making proxied tool startup faster and more resilient (#1071)
  • The client cache and session OTel meters are now injectable, so embedders can supply their own instrumentation (#1073)

Don't miss a new mcp-grafana release

NewReleases is sending notifications on new releases.