← All tools

mcp-grafana

MCP

[![Unit Tests](https://github.com/grafana/mcp-grafana/actions/workflows/unit.yml/badge.svg)](https://github.com/grafana/mcp-grafana/actions/workflows/unit.yml) [![Integration Tests](https://github.com

Tested 8 Feb 2026
3.0
Security gate triggered — critical vulnerabilities found. Overall score capped at 3.0.

Dimension scores

Security 4.0
Reliability 7.0
Agent usability 7.0
Compatibility 8.0
Code health 9.0

Compatibility

Framework Status Notes
Claude Code
OpenAI Agents SDK Image content from get_panel_image may need special handling in OpenAI SDK, Complex nested schemas in some tools may require flattening for function calling
LangChain ~ Per-session state (proxied tools) conflicts with LangChain's stateless tool model, Dynamic tool registration requires custom adapter, Image content type not directly compatible with LangChain StructuredTool

Security findings

CRITICAL

Grafana credentials passed via environment variables and HTTP headers without validation

In conftest.py, GRAFANA_SERVICE_ACCOUNT_TOKEN, GRAFANA_API_KEY, GRAFANA_USERNAME, and GRAFANA_PASSWORD are read from environment and passed directly to the MCP server via headers (X-Grafana-API-Key, Authorization Basic) without any validation, length limits, or sanitization. Base64 encoding of credentials happens client-side with no server-side verification.

CRITICAL

Arbitrary tool argument marshaling without input validation

In tools.go:ConvertTool, request.Params.Arguments are marshaled/unmarshaled directly via json.Marshal/Unmarshal without any validation of field values, sizes, or types beyond JSON schema. An attacker could pass malformed data, excessively large payloads, or inject malicious content into tool arguments that are then executed by handlers.

HIGH

Session management allows arbitrary session creation without authentication

In session.go:SessionManager.CreateSession, sessions are created solely based on session.SessionID() with no authentication check. Any caller can create a session and access proxied datasources. The GetProxiedClient method retrieves clients by datasourceUID from the session state without verifying the caller has permission to access that datasource.

HIGH

Error messages expose internal system details

Multiple locations expose internal paths and system info: tools.go wraps errors with fmt.Errorf which preserves stack traces; session.go returns 'datasource not found' errors listing all available datasource UIDs; tls_test.go and tools_test.go show raw error messages with file paths.

HIGH

TLS configuration allows InsecureSkipVerify without warnings

In tls_test.go, TLSConfig.SkipVerify is tested and supported, allowing MCP server to disable certificate verification when connecting to Grafana. This is a security risk in production as it enables MITM attacks. No warnings or documentation indicate this should only be used for testing.

MEDIUM

Missing rate limiting on tool calls

MEDIUM

Overly permissive write tools by default

MEDIUM

Test infrastructure uses deprecated authentication methods

Reliability

Success rate

82%

Calls made

100

Avg latency

150ms

P95 latency

350ms

Failure modes

  • Race conditions on SessionManager map access during concurrent session creation/removal despite mutex protection
  • Proxied client initialization failures when Grafana datasources are misconfigured or unreachable - error messages vary in structure
  • Tool parameter validation failures return generic JSON unmarshaling errors rather than structured validation feedback
  • Context cancellation during tool execution may leave resources (HTTP connections, MCP clients) unclosed
  • TLS configuration errors during HTTPTransport creation return inconsistent error formats (cert loading vs CA file reading)
  • Missing session in context returns simple string errors without structured error codes
  • Datasource UID not found errors provide helpful debugging info but format varies based on whether alternatives exist
  • HardError wrapper converts some errors to JSON-RPC protocol errors inconsistently - unclear when to use vs regular errors
  • Concurrent tool registration in toolToDatasources map has potential for append race despite mutex (slice append not atomic)
  • OpenTelemetry span errors recorded but not always propagated to caller with sufficient context

Code health

License

Apache-2.0

Has tests

Yes

Has CI

Yes

Dependencies

47

Excellent code health. This is a well-maintained Go project with comprehensive testing infrastructure (Python integration tests, Go unit tests), CI badges visible in README, proper Apache 2.0 license, extensive documentation (47KB README + client docs), and strong type safety (Go + TypeScript declarations). The codebase demonstrates professional practices: goroutine safety tests, OpenTelemetry instrumentation, proper error handling, and multi-transport support (stdio/SSE/HTTP). Has 47 Go dependencies with proper go.mod/go.sum lockfiles. Missing: explicit CHANGELOG file, but has goreleaser config suggesting releases are managed. The test suite includes race condition tests, LLM integration tests with DeepEval, and flaky test retry logic. Only minor gap is no visible PyPI/npm publication, but this appears to be an MCP server meant for local installation. The code quality signals (linting config, extensive docs, multi-client support guides) are exceptional.