Documentation
¶
Index ¶
- Constants
- Variables
- func BuildTransport(cfg *GrafanaConfig, base http.RoundTripper) (http.RoundTripper, error)
- func ComposeHTTPContextFuncs(funcs ...httpContextFunc) server.HTTPContextFunc
- func ComposeSSEContextFuncs(funcs ...httpContextFunc) server.SSEContextFunc
- func ComposeStdioContextFuncs(funcs ...server.StdioContextFunc) server.StdioContextFunc
- func ComposedHTTPContextFunc(config GrafanaConfig, cache ...*ClientCache) server.HTTPContextFunc
- func ComposedSSEContextFunc(config GrafanaConfig, cache ...*ClientCache) server.SSEContextFunc
- func ComposedStdioContextFunc(config GrafanaConfig) server.StdioContextFunc
- func ConvertTool[T any, R any](name, description string, toolHandler ToolHandlerFunc[T, R], ...) (mcp.Tool, server.ToolHandlerFunc, error)
- func IncidentClientFromContext(ctx context.Context) *incident.Client
- func MustWithOnBehalfOfAuth(ctx context.Context, accessToken, userToken string) context.Context
- func UserAgent() string
- func WithGrafanaClient(ctx context.Context, c *GrafanaClient) context.Context
- func WithGrafanaConfig(ctx context.Context, config GrafanaConfig) context.Context
- func WithIncidentClient(ctx context.Context, client *incident.Client) context.Context
- func WithOnBehalfOfAuth(ctx context.Context, accessToken, userToken string) (context.Context, error)
- func WithProxiedTools(enabled bool) toolManagerOption
- type APIGroup
- type APIGroupList
- type ClientCache
- func (c *ClientCache) Close()
- func (c *ClientCache) GetOrCreateGrafanaClient(key clientCacheKey, createFn func() *GrafanaClient) *GrafanaClient
- func (c *ClientCache) GetOrCreateIncidentClient(key clientCacheKey, createFn func() *incident.Client) *incident.Client
- func (c *ClientCache) Size() (grafana, incident int)
- type DiscoveredDatasource
- type ExtraHeadersRoundTripper
- type GrafanaClient
- type GrafanaConfig
- type GroupVersionInfo
- type HardError
- type KubernetesAPIError
- type KubernetesClient
- func (c *KubernetesClient) Discover(ctx context.Context) (*ResourceRegistry, error)
- func (c *KubernetesClient) Get(ctx context.Context, desc ResourceDescriptor, namespace, name string) (map[string]interface{}, error)
- func (c *KubernetesClient) List(ctx context.Context, desc ResourceDescriptor, namespace string, ...) (*ResourceList, error)
- type ListOptions
- type MCPDatasourceConfig
- type OrgIDRoundTripper
- type ProxiedClient
- type ProxiedToolHandler
- type ResourceDescriptor
- type ResourceGroup
- type ResourceList
- type ResourceRegistry
- type SessionManager
- func (sm *SessionManager) Close()
- func (sm *SessionManager) CreateSession(ctx context.Context, session server.ClientSession)
- func (sm *SessionManager) GetProxiedClient(ctx context.Context, datasourceType, datasourceUID string) (*ProxiedClient, error)
- func (sm *SessionManager) GetSession(sessionID string) (*SessionState, bool)
- func (sm *SessionManager) RemoveSession(ctx context.Context, session server.ClientSession)
- type SessionManagerOption
- type SessionState
- type TLSConfig
- type Tool
- type ToolHandlerFunc
- type ToolManager
- type UserAgentTransport
Constants ¶
const ( // DefaultGrafanaClientTimeout is the default timeout for Grafana HTTP client requests. DefaultGrafanaClientTimeout = 10 * time.Second )
const ( // DefaultSessionTTL is the default time-to-live for idle sessions. // Sessions with no activity for this duration are reaped. DefaultSessionTTL = 30 * time.Minute )
Variables ¶
var ExtractGrafanaClientFromEnv server.StdioContextFunc = func(ctx context.Context) context.Context { grafanaURL, apiKey := urlAndAPIKeyFromEnv() if grafanaURL == "" { grafanaURL = defaultGrafanaURL } auth := userAndPassFromEnv() grafanaClient := NewGrafanaClient(ctx, grafanaURL, apiKey, auth) return WithGrafanaClient(ctx, grafanaClient) }
ExtractGrafanaClientFromEnv is a StdioContextFunc that creates and injects a Grafana client into the context. It uses configuration from GRAFANA_URL, GRAFANA_SERVICE_ACCOUNT_TOKEN (or deprecated GRAFANA_API_KEY), GRAFANA_USERNAME/PASSWORD environment variables to initialize the client with proper authentication.
var ExtractGrafanaClientFromHeaders httpContextFunc = func(ctx context.Context, req *http.Request) context.Context { config := GrafanaConfigFromContext(ctx) if config.OrgID == 0 { slog.Warn("No org ID found in request headers or environment variables, using default org. Set GRAFANA_ORG_ID or pass X-Grafana-Org-Id header to target a specific org.") } u, apiKey, basicAuth, _ := extractKeyGrafanaInfoFromReq(req) slog.Debug("Creating Grafana client", "url", u, "api_key_set", apiKey != "", "basic_auth_set", basicAuth != nil) grafanaClient := NewGrafanaClient(ctx, u, apiKey, basicAuth) return WithGrafanaClient(ctx, grafanaClient) }
ExtractGrafanaClientFromHeaders is a HTTPContextFunc that creates and injects a Grafana client into the context. It prioritizes configuration from HTTP headers (X-Grafana-URL, X-Grafana-API-Key) over environment variables for multi-tenant scenarios.
var ExtractGrafanaInfoFromEnv server.StdioContextFunc = func(ctx context.Context) context.Context { u, apiKey, basicAuth, orgID := extractKeyGrafanaInfoFromEnv() parsedURL, err := url.Parse(u) if err != nil { panic(fmt.Errorf("invalid Grafana URL %s: %w", u, err)) } extraHeaders := extraHeadersFromEnv() slog.Info("Using Grafana configuration", "url", parsedURL.Redacted(), "api_key_set", apiKey != "", "basic_auth_set", basicAuth != nil, "org_id", orgID, "extra_headers_count", len(extraHeaders)) config := GrafanaConfigFromContext(ctx) config.URL = u config.APIKey = apiKey config.BasicAuth = basicAuth config.OrgID = orgID config.ExtraHeaders = extraHeaders return WithGrafanaConfig(ctx, config) }
ExtractGrafanaInfoFromEnv is a StdioContextFunc that extracts Grafana configuration from environment variables. It reads GRAFANA_URL and GRAFANA_SERVICE_ACCOUNT_TOKEN (or deprecated GRAFANA_API_KEY) environment variables and adds the configuration to the context for use by Grafana clients.
var ExtractGrafanaInfoFromHeaders httpContextFunc = func(ctx context.Context, req *http.Request) context.Context { u, apiKey, basicAuth, orgID := extractKeyGrafanaInfoFromReq(req) config := GrafanaConfigFromContext(ctx) config.URL = u config.APIKey = apiKey config.BasicAuth = basicAuth config.OrgID = orgID config.ExtraHeaders = mergeHeaders(extraHeadersFromEnv(), forwardedHeadersFromRequest(req)) return WithGrafanaConfig(ctx, config) }
ExtractGrafanaInfoFromHeaders is a HTTPContextFunc that extracts Grafana configuration from HTTP request headers. It reads X-Grafana-URL and X-Grafana-API-Key headers, falling back to environment variables if headers are not present. Headers listed in GRAFANA_FORWARD_HEADERS are copied from the incoming request and merged with GRAFANA_EXTRA_HEADERS.
var ExtractIncidentClientFromEnv server.StdioContextFunc = func(ctx context.Context) context.Context { grafanaURL, apiKey := urlAndAPIKeyFromEnv() if grafanaURL == "" { grafanaURL = defaultGrafanaURL } incidentURL := fmt.Sprintf("%s/api/plugins/grafana-irm-app/resources/api/v1/", grafanaURL) parsedURL, err := url.Parse(incidentURL) if err != nil { panic(fmt.Errorf("invalid incident URL %s: %w", incidentURL, err)) } slog.Debug("Creating Incident client", "url", parsedURL.Redacted(), "api_key_set", apiKey != "") client := incident.NewClient(incidentURL, apiKey) config := GrafanaConfigFromContext(ctx) transport, err := BuildTransport(&config, nil) if err != nil { slog.Error("Failed to create custom transport for incident client, using default", "error", err) } else { orgIDWrapped := NewOrgIDRoundTripper(transport, config.OrgID) client.HTTPClient.Transport = wrapWithUserAgent(orgIDWrapped) if config.TLSConfig != nil { slog.Debug("Using custom TLS configuration, user agent, and org ID support for incident client", "cert_file", config.TLSConfig.CertFile, "ca_file", config.TLSConfig.CAFile, "skip_verify", config.TLSConfig.SkipVerify) } } return context.WithValue(ctx, incidentClientKey{}, client) }
ExtractIncidentClientFromEnv is a StdioContextFunc that creates and injects a Grafana Incident client into the context. It configures the client using environment variables and applies any custom TLS settings from the context.
var ExtractIncidentClientFromHeaders httpContextFunc = func(ctx context.Context, req *http.Request) context.Context { grafanaURL, apiKey, _, orgID := extractKeyGrafanaInfoFromReq(req) incidentURL := fmt.Sprintf("%s/api/plugins/grafana-irm-app/resources/api/v1/", grafanaURL) client := incident.NewClient(incidentURL, apiKey) config := GrafanaConfigFromContext(ctx) transport, err := BuildTransport(&config, nil) if err != nil { slog.Error("Failed to create custom transport for incident client, using default", "error", err) } else { orgIDWrapped := NewOrgIDRoundTripper(transport, orgID) client.HTTPClient.Transport = wrapWithUserAgent(orgIDWrapped) if config.TLSConfig != nil { slog.Debug("Using custom TLS configuration, user agent, and org ID support for incident client", "cert_file", config.TLSConfig.CertFile, "ca_file", config.TLSConfig.CAFile, "skip_verify", config.TLSConfig.SkipVerify) } } return context.WithValue(ctx, incidentClientKey{}, client) }
ExtractIncidentClientFromHeaders is a HTTPContextFunc that creates and injects a Grafana Incident client into the context. It uses HTTP headers for configuration with environment variable fallbacks, enabling per-request incident management configuration.
var Version = sync.OnceValue(func() string { v := "(devel)" if bi, ok := debug.ReadBuildInfo(); ok && bi.Main.Version != "" { v = bi.Main.Version } return v })
Version returns the version of the mcp-grafana binary. It uses runtime/debug to fetch version information from the build, returning "(devel)" for local development builds. The version is computed once and cached for performance.
Functions ¶
func BuildTransport ¶ added in v0.10.0
func BuildTransport(cfg *GrafanaConfig, base http.RoundTripper) (http.RoundTripper, error)
func ComposeHTTPContextFuncs ¶ added in v0.4.0
func ComposeHTTPContextFuncs(funcs ...httpContextFunc) server.HTTPContextFunc
ComposeHTTPContextFuncs composes multiple HTTPContextFuncs into a single one. This enables chaining of context modifications for HTTP transport, allowing modular setup of authentication, clients, and configuration.
func ComposeSSEContextFuncs ¶
func ComposeSSEContextFuncs(funcs ...httpContextFunc) server.SSEContextFunc
ComposeSSEContextFuncs composes multiple SSEContextFuncs into a single one. This enables chaining of context modifications for Server-Sent Events transport, such as extracting headers and setting up clients.
func ComposeStdioContextFuncs ¶
func ComposeStdioContextFuncs(funcs ...server.StdioContextFunc) server.StdioContextFunc
ComposeStdioContextFuncs composes multiple StdioContextFuncs into a single one. Functions are applied in order, allowing each to modify the context before passing it to the next.
func ComposedHTTPContextFunc ¶ added in v0.4.0
func ComposedHTTPContextFunc(config GrafanaConfig, cache ...*ClientCache) server.HTTPContextFunc
ComposedHTTPContextFunc returns a HTTPContextFunc that comprises all predefined HTTPContextFuncs. It provides the complete context setup for HTTP transport, including header-based authentication and client configuration. If cache is non-nil, clients are cached by credentials to avoid per-request transport allocation.
func ComposedSSEContextFunc ¶
func ComposedSSEContextFunc(config GrafanaConfig, cache ...*ClientCache) server.SSEContextFunc
ComposedSSEContextFunc returns a SSEContextFunc that comprises all predefined SSEContextFuncs. It sets up the complete context for SSE transport, extracting configuration from HTTP headers with environment variable fallbacks. If cache is non-nil, clients are cached by credentials to avoid per-request transport allocation.
func ComposedStdioContextFunc ¶
func ComposedStdioContextFunc(config GrafanaConfig) server.StdioContextFunc
ComposedStdioContextFunc returns a StdioContextFunc that comprises all predefined StdioContextFuncs. It sets up the complete context for stdio transport including Grafana configuration, client initialization from environment variables, and incident management support.
func ConvertTool ¶
func ConvertTool[T any, R any](name, description string, toolHandler ToolHandlerFunc[T, R], options ...mcp.ToolOption) (mcp.Tool, server.ToolHandlerFunc, error)
ConvertTool converts a toolHandler function to an MCP Tool and ToolHandlerFunc. The toolHandler must accept a context.Context and a struct with jsonschema tags for parameter documentation. The struct fields define the tool's input schema, while the return value can be a string, struct, or *mcp.CallToolResult. This function automatically generates JSON schema from the struct type and wraps the handler with OpenTelemetry instrumentation.
func IncidentClientFromContext ¶
IncidentClientFromContext retrieves the Grafana Incident client from the context. Returns nil if no client has been set, indicating that incident management features are not available.
func MustWithOnBehalfOfAuth ¶ added in v0.3.0
MustWithOnBehalfOfAuth adds the access and user tokens to the context, panicking if either are empty. This is a convenience wrapper around WithOnBehalfOfAuth for cases where token validation has already occurred.
func UserAgent ¶ added in v0.6.3
func UserAgent() string
UserAgent returns the user agent string for HTTP requests. It includes the mcp-grafana identifier and version number for proper request attribution and debugging.
func WithGrafanaClient ¶
func WithGrafanaClient(ctx context.Context, c *GrafanaClient) context.Context
WithGrafanaClient sets the Grafana client in the context. The client can be retrieved using GrafanaClientFromContext and will be used by all Grafana-related tools in the MCP server.
func WithGrafanaConfig ¶ added in v0.5.0
func WithGrafanaConfig(ctx context.Context, config GrafanaConfig) context.Context
WithGrafanaConfig adds Grafana configuration to the context. This configuration includes API credentials, debug settings, and TLS options that will be used by all Grafana clients created from this context.
func WithIncidentClient ¶
WithIncidentClient sets the Grafana Incident client in the context. This client is used for managing incidents, activities, and other IRM (Incident Response Management) operations.
func WithOnBehalfOfAuth ¶ added in v0.3.0
func WithOnBehalfOfAuth(ctx context.Context, accessToken, userToken string) (context.Context, error)
WithOnBehalfOfAuth adds the Grafana access token and user token to the Grafana config. These tokens enable on-behalf-of authentication in Grafana Cloud, allowing the MCP server to act on behalf of a specific user with their permissions.
func WithProxiedTools ¶ added in v0.7.8
func WithProxiedTools(enabled bool) toolManagerOption
WithProxiedTools sets whether proxied tools are enabled
Types ¶
type APIGroup ¶ added in v0.11.4
type APIGroup struct {
Name string `json:"name"`
Versions []GroupVersionInfo `json:"versions"`
PreferredVersion GroupVersionInfo `json:"preferredVersion"`
}
APIGroup represents a single API group in the discovery response.
type APIGroupList ¶ added in v0.11.4
APIGroupList represents the response from GET /apis (Kubernetes API discovery).
type ClientCache ¶ added in v0.11.4
type ClientCache struct {
// contains filtered or unexported fields
}
ClientCache caches HTTP clients keyed by credentials to avoid creating new transports per request. This prevents the memory leak described in https://github.com/grafana/mcp-grafana/issues/682.
func NewClientCache ¶ added in v0.11.4
func NewClientCache() *ClientCache
NewClientCache creates a new client cache.
func (*ClientCache) Close ¶ added in v0.11.4
func (c *ClientCache) Close()
Close cleans up cached clients. For incident clients, idle connections are closed via the underlying HTTP transport. Grafana clients use a go-openapi runtime whose transport is set via reflection, so we clear the map and let the GC reclaim resources.
func (*ClientCache) GetOrCreateGrafanaClient ¶ added in v0.11.4
func (c *ClientCache) GetOrCreateGrafanaClient(key clientCacheKey, createFn func() *GrafanaClient) *GrafanaClient
GetOrCreateGrafanaClient returns a cached Grafana client for the given key, or creates one using createFn if no cached client exists. The createFn is called outside the cache lock via singleflight to avoid blocking concurrent cache reads during slow client creation (e.g. network I/O).
func (*ClientCache) GetOrCreateIncidentClient ¶ added in v0.11.4
func (c *ClientCache) GetOrCreateIncidentClient(key clientCacheKey, createFn func() *incident.Client) *incident.Client
GetOrCreateIncidentClient returns a cached incident client for the given key, or creates one using createFn if no cached client exists. The createFn is called outside the cache lock via singleflight to avoid blocking concurrent cache reads during slow client creation.
func (*ClientCache) Size ¶ added in v0.11.4
func (c *ClientCache) Size() (grafana, incident int)
Size returns the number of cached clients (for testing/metrics).
type DiscoveredDatasource ¶ added in v0.7.8
type DiscoveredDatasource struct {
UID string
Name string
Type string
MCPURL string // The MCP endpoint URL
}
DiscoveredDatasource represents a datasource that supports MCP
type ExtraHeadersRoundTripper ¶ added in v0.10.0
type ExtraHeadersRoundTripper struct {
// contains filtered or unexported fields
}
func NewExtraHeadersRoundTripper ¶ added in v0.10.0
func NewExtraHeadersRoundTripper(rt http.RoundTripper, headers map[string]string) *ExtraHeadersRoundTripper
type GrafanaClient ¶ added in v0.11.4
type GrafanaClient struct {
*client.GrafanaHTTPAPI
// PublicURL is the public-facing URL of the Grafana instance, fetched from
// /api/frontend/settings (the appUrl field). It may differ from the configured
// URL when the MCP server accesses Grafana via an internal URL behind a load
// balancer or reverse proxy.
PublicURL string
}
GrafanaClient wraps the Grafana HTTP API client with additional metadata fetched from the Grafana instance, such as the public URL. This allows the MCP server to generate user-facing links using the public URL even when it accesses Grafana via an internal URL.
func GrafanaClientFromContext ¶
func GrafanaClientFromContext(ctx context.Context) *GrafanaClient
GrafanaClientFromContext retrieves the Grafana client from the context. Returns nil if no client has been set, which tools should handle gracefully with appropriate error messages.
func NewGrafanaClient ¶ added in v0.4.0
func NewGrafanaClient(ctx context.Context, grafanaURL, apiKey string, auth *url.Userinfo) *GrafanaClient
NewGrafanaClient creates a Grafana client with the provided URL and API key. The client is automatically configured with the correct HTTP scheme, debug settings from context, custom TLS configuration if present, and OpenTelemetry instrumentation for distributed tracing. It also fetches the Grafana instance's public URL from /api/frontend/settings for use in deep link generation. The org ID is read from the GrafanaConfig in the context, which should be set by ExtractGrafanaInfoFromEnv or ExtractGrafanaInfoFromHeaders before calling this function.
type GrafanaConfig ¶ added in v0.5.0
type GrafanaConfig struct {
// Debug enables debug mode for the Grafana client.
Debug bool
// IncludeArgumentsInSpans enables logging of tool arguments in OpenTelemetry spans.
// This should only be enabled in non-production environments or when you're certain
// the arguments don't contain PII. Defaults to false for safety.
// Note: OpenTelemetry spans are always created for context propagation, but arguments
// are only included when this flag is enabled.
IncludeArgumentsInSpans bool
// URL is the URL of the Grafana instance.
URL string
// APIKey is the API key or service account token for the Grafana instance.
// It may be empty if we are using on-behalf-of auth.
APIKey string
// Credentials if user is using basic auth
BasicAuth *url.Userinfo
// OrgID is the organization ID to use for multi-org support.
// When set, it will be sent as X-Grafana-Org-Id header regardless of authentication method.
// Works with service account tokens, API keys, and basic authentication.
OrgID int64
// AccessToken is the Grafana Cloud access policy token used for on-behalf-of auth in Grafana Cloud.
AccessToken string
// IDToken is an ID token identifying the user for the current request.
// It comes from the `X-Grafana-Id` header sent from Grafana to plugin backends.
// It is used for on-behalf-of auth in Grafana Cloud.
IDToken string
// TLSConfig holds TLS configuration for all Grafana clients.
TLSConfig *TLSConfig
// Timeout specifies a time limit for requests made by the Grafana client.
// A Timeout of zero means no timeout.
// Default is 10 seconds.
Timeout time.Duration
// ExtraHeaders contains additional HTTP headers to send with all Grafana API requests.
// Parsed from GRAFANA_EXTRA_HEADERS environment variable as JSON object.
ExtraHeaders map[string]string
// MaxLokiLogLimit is the maximum number of log lines that can be returned
// from Loki queries.
MaxLokiLogLimit int
// BaseTransport is an optional base HTTP transport used as the innermost
// layer of the middleware chain in NewGrafanaClient. When set, it replaces
// the default http.Transport that NewGrafanaClient would otherwise create.
// The caller can use this to provide a pre-configured transport with custom
// connection pooling, timeouts, or tracing instrumentation.
// Note: NewGrafanaClient still wraps this transport with ExtraHeaders,
// OrgID, UserAgent, and otelhttp layers.
BaseTransport http.RoundTripper
}
GrafanaConfig represents the full configuration for Grafana clients. It includes connection details, authentication credentials, debug settings, and TLS options used throughout the MCP server's lifecycle.
func GrafanaConfigFromContext ¶ added in v0.5.0
func GrafanaConfigFromContext(ctx context.Context) GrafanaConfig
GrafanaConfigFromContext extracts Grafana configuration from the context. If no config is found, returns a zero-value GrafanaConfig. This function is typically used by internal components to access configuration set earlier in the request lifecycle.
type GroupVersionInfo ¶ added in v0.11.4
type GroupVersionInfo struct {
GroupVersion string `json:"groupVersion"`
Version string `json:"version"`
}
GroupVersionInfo contains version information for an API group.
type HardError ¶ added in v0.9.0
type HardError struct {
Err error
}
HardError wraps an error to indicate it should propagate as a JSON-RPC protocol error rather than being converted to CallToolResult with IsError=true. Use sparingly for non-recoverable failures (e.g., missing auth).
type KubernetesAPIError ¶ added in v0.11.4
KubernetesAPIError is returned when the server responds with a non-2xx status.
func (*KubernetesAPIError) Error ¶ added in v0.11.4
func (e *KubernetesAPIError) Error() string
type KubernetesClient ¶ added in v0.11.4
type KubernetesClient struct {
// BaseURL is the root URL of the Grafana instance (e.g. "http://localhost:3000").
BaseURL string
// HTTPClient is the underlying HTTP client used for requests.
// If nil, http.DefaultClient is used.
HTTPClient *http.Client
}
KubernetesClient is a lightweight, generic HTTP client for Grafana's Kubernetes-style APIs (/apis/...). It uses unstructured data (map[string]interface{}) so callers are not tied to specific Go types.
Authentication is read from the GrafanaConfig in the request context, following the same priority as the rest of mcp-grafana:
- AccessToken + IDToken (on-behalf-of)
- APIKey (bearer token)
- BasicAuth
func NewKubernetesClient ¶ added in v0.11.4
func NewKubernetesClient(ctx context.Context) (*KubernetesClient, error)
NewKubernetesClient creates a KubernetesClient from the GrafanaConfig in ctx. It reuses BuildTransport so TLS, extra headers, OrgID, and user-agent are handled the same way as for the legacy OpenAPI client.
func (*KubernetesClient) Discover ¶ added in v0.11.4
func (c *KubernetesClient) Discover(ctx context.Context) (*ResourceRegistry, error)
Discover calls GET /apis and returns a ResourceRegistry describing available API groups and their versions.
func (*KubernetesClient) Get ¶ added in v0.11.4
func (c *KubernetesClient) Get(ctx context.Context, desc ResourceDescriptor, namespace, name string) (map[string]interface{}, error)
Get fetches a single resource by name. Returns the full Kubernetes-style object as unstructured data.
func (*KubernetesClient) List ¶ added in v0.11.4
func (c *KubernetesClient) List(ctx context.Context, desc ResourceDescriptor, namespace string, opts *ListOptions) (*ResourceList, error)
List fetches a collection of resources.
type ListOptions ¶ added in v0.11.4
type ListOptions struct {
// LabelSelector filters results by label (e.g. "app=foo").
LabelSelector string
// Limit caps the number of items returned.
Limit int
// Continue is a pagination token from a previous list response.
Continue string
}
ListOptions controls the behaviour of a List call.
type MCPDatasourceConfig ¶ added in v0.7.8
MCPDatasourceConfig defines configuration for a datasource type that supports MCP
type OrgIDRoundTripper ¶ added in v0.7.8
type OrgIDRoundTripper struct {
// contains filtered or unexported fields
}
OrgIDRoundTripper wraps an http.RoundTripper to add the X-Grafana-Org-Id header.
func NewOrgIDRoundTripper ¶ added in v0.7.8
func NewOrgIDRoundTripper(rt http.RoundTripper, orgID int64) *OrgIDRoundTripper
type ProxiedClient ¶ added in v0.7.8
type ProxiedClient struct {
DatasourceUID string
DatasourceName string
DatasourceType string
Client *mcp_client.Client
Tools []mcp.Tool
// contains filtered or unexported fields
}
ProxiedClient represents a connection to a remote MCP server (e.g., Tempo datasource)
func NewProxiedClient ¶ added in v0.7.8
func NewProxiedClient(ctx context.Context, datasourceUID, datasourceName, datasourceType, mcpEndpoint string) (*ProxiedClient, error)
NewProxiedClient creates a new connection to a remote MCP server
func (*ProxiedClient) CallTool ¶ added in v0.7.8
func (pc *ProxiedClient) CallTool(ctx context.Context, toolName string, arguments map[string]any) (*mcp.CallToolResult, error)
CallTool forwards a tool call to the remote MCP server
func (*ProxiedClient) Close ¶ added in v0.7.8
func (pc *ProxiedClient) Close() error
Close closes the connection to the remote MCP server
func (*ProxiedClient) ListTools ¶ added in v0.7.8
func (pc *ProxiedClient) ListTools() []mcp.Tool
ListTools returns the tools available from this remote server Note: This method doesn't take a context parameter as the tools are cached locally
type ProxiedToolHandler ¶ added in v0.7.8
type ProxiedToolHandler struct {
// contains filtered or unexported fields
}
ProxiedToolHandler implements the CallToolHandler interface for proxied tools
func NewProxiedToolHandler ¶ added in v0.7.8
func NewProxiedToolHandler(sm *SessionManager, tm *ToolManager, toolName string) *ProxiedToolHandler
NewProxiedToolHandler creates a new handler for a proxied tool
func (*ProxiedToolHandler) Handle ¶ added in v0.7.8
func (h *ProxiedToolHandler) Handle(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error)
Handle forwards the tool call to the appropriate remote MCP server
type ResourceDescriptor ¶ added in v0.11.4
type ResourceDescriptor struct {
Group string // e.g. "dashboard.grafana.app"
Version string // e.g. "v2beta1"
Resource string // plural name, e.g. "dashboards"
}
ResourceDescriptor describes a Kubernetes-style API resource in Grafana. It contains enough information to construct API paths for any k8s-style resource.
func (ResourceDescriptor) BasePath ¶ added in v0.11.4
func (d ResourceDescriptor) BasePath(namespace string) string
BasePath returns the API path prefix for this resource, including namespace. For example: /apis/dashboard.grafana.app/v2beta1/namespaces/default/dashboards
type ResourceGroup ¶ added in v0.11.4
ResourceGroup holds information about a single API group discovered from /apis.
type ResourceList ¶ added in v0.11.4
type ResourceList struct {
Kind string `json:"kind"`
APIVersion string `json:"apiVersion"`
Items []map[string]interface{} `json:"items"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
}
ResourceList is the response shape for a Kubernetes-style list request.
type ResourceRegistry ¶ added in v0.11.4
type ResourceRegistry struct {
// contains filtered or unexported fields
}
ResourceRegistry maps API group names to their available resources and versions. It is built from the /apis discovery response (APIGroupList).
ResourceRegistry is immutable after construction via NewResourceRegistry and is safe for concurrent reads from multiple goroutines without synchronization.
func NewResourceRegistry ¶ added in v0.11.4
func NewResourceRegistry(apiGroupList *APIGroupList) *ResourceRegistry
NewResourceRegistry creates a ResourceRegistry from an APIGroupList.
func (*ResourceRegistry) GetGroup ¶ added in v0.11.4
func (r *ResourceRegistry) GetGroup(name string) *ResourceGroup
GetGroup returns the ResourceGroup for the given API group name, or nil if not found.
func (*ResourceRegistry) Groups ¶ added in v0.11.4
func (r *ResourceRegistry) Groups() []string
Groups returns a list of all known API group names.
func (*ResourceRegistry) HasGroup ¶ added in v0.11.4
func (r *ResourceRegistry) HasGroup(name string) bool
HasGroup returns true if the registry contains the given API group.
func (*ResourceRegistry) PreferredVersion ¶ added in v0.11.4
func (r *ResourceRegistry) PreferredVersion(group string) string
PreferredVersion returns the preferred version for the given API group. Returns an empty string if the group is not found.
type SessionManager ¶ added in v0.7.8
type SessionManager struct {
// contains filtered or unexported fields
}
SessionManager manages client sessions and their state
func NewSessionManager ¶ added in v0.7.8
func NewSessionManager(opts ...SessionManagerOption) *SessionManager
func (*SessionManager) Close ¶ added in v0.11.4
func (sm *SessionManager) Close()
Close stops the reaper goroutine and cleans up all remaining sessions. It is safe to call concurrently and multiple times.
func (*SessionManager) CreateSession ¶ added in v0.7.8
func (sm *SessionManager) CreateSession(ctx context.Context, session server.ClientSession)
func (*SessionManager) GetProxiedClient ¶ added in v0.7.8
func (sm *SessionManager) GetProxiedClient(ctx context.Context, datasourceType, datasourceUID string) (*ProxiedClient, error)
GetProxiedClient retrieves a proxied client for the given datasource
func (*SessionManager) GetSession ¶ added in v0.7.8
func (sm *SessionManager) GetSession(sessionID string) (*SessionState, bool)
func (*SessionManager) RemoveSession ¶ added in v0.7.8
func (sm *SessionManager) RemoveSession(ctx context.Context, session server.ClientSession)
type SessionManagerOption ¶ added in v0.11.4
type SessionManagerOption func(*SessionManager)
SessionManagerOption configures a SessionManager.
func WithSessionTTL ¶ added in v0.11.4
func WithSessionTTL(ttl time.Duration) SessionManagerOption
WithSessionTTL sets the TTL for idle sessions. Sessions idle longer than this duration are automatically reaped. A zero or negative value disables the reaper.
type SessionState ¶ added in v0.7.8
type SessionState struct {
// contains filtered or unexported fields
}
SessionState holds the state for a single client session
type TLSConfig ¶ added in v0.6.0
TLSConfig holds TLS configuration for Grafana clients. It supports mutual TLS authentication with client certificates, custom CA certificates for server verification, and development options like skipping certificate verification.
func (*TLSConfig) CreateTLSConfig ¶ added in v0.6.0
CreateTLSConfig creates a *tls.Config from TLSConfig. It supports client certificates, custom CA certificates, and the option to skip TLS verification for development environments.
func (*TLSConfig) HTTPTransport ¶ added in v0.6.0
HTTPTransport creates an HTTP transport with custom TLS configuration. It clones the provided transport and applies the TLS settings, preserving other transport configurations like timeouts and connection pools.
type Tool ¶
type Tool struct {
Tool mcp.Tool
Handler server.ToolHandlerFunc
}
Tool represents a tool definition and its handler function for the MCP server. It encapsulates both the tool metadata (name, description, schema) and the function that executes when the tool is called. The simplest way to create a Tool is to use MustTool for compile-time tool creation, or ConvertTool if you need runtime tool creation with proper error handling.
func MustTool ¶
func MustTool[T any, R any]( name, description string, toolHandler ToolHandlerFunc[T, R], options ...mcp.ToolOption, ) Tool
MustTool creates a new Tool from the given name, description, and toolHandler. It panics if the tool cannot be created, making it suitable for compile-time tool definitions where creation errors indicate programming mistakes.
type ToolHandlerFunc ¶
ToolHandlerFunc is the type of a handler function for a tool. T is the request parameter type (must be a struct with jsonschema tags), and R is the response type which can be a string, struct, or *mcp.CallToolResult.
type ToolManager ¶ added in v0.7.8
type ToolManager struct {
// contains filtered or unexported fields
}
ToolManager manages proxied tools (either per-session or server-wide)
func NewToolManager ¶ added in v0.7.8
func NewToolManager(sm *SessionManager, mcpServer *server.MCPServer, opts ...toolManagerOption) *ToolManager
NewToolManager creates a new ToolManager
func (*ToolManager) GetServerClient ¶ added in v0.7.8
func (tm *ToolManager) GetServerClient(datasourceType, datasourceUID string) (*ProxiedClient, error)
GetServerClient retrieves a proxied client from server-level storage (for stdio transport)
func (*ToolManager) InitializeAndRegisterProxiedTools ¶ added in v0.7.8
func (tm *ToolManager) InitializeAndRegisterProxiedTools(ctx context.Context, session server.ClientSession)
InitializeAndRegisterProxiedTools discovers datasources, creates clients, and registers tools per-session This should be called in OnBeforeListTools and OnBeforeCallTool hooks for HTTP/SSE transports
func (*ToolManager) InitializeAndRegisterServerTools ¶ added in v0.7.8
func (tm *ToolManager) InitializeAndRegisterServerTools(ctx context.Context) error
InitializeAndRegisterServerTools discovers datasources and registers tools on the server (for stdio transport) This should be called once at server startup for single-tenant stdio servers
type UserAgentTransport ¶ added in v0.6.3
type UserAgentTransport struct {
UserAgent string
// contains filtered or unexported fields
}
UserAgentTransport wraps an http.RoundTripper to add a custom User-Agent header. This ensures all HTTP requests from the MCP server are properly identified with version information for debugging and analytics.
func NewUserAgentTransport ¶ added in v0.6.3
func NewUserAgentTransport(rt http.RoundTripper, userAgent ...string) *UserAgentTransport
NewUserAgentTransport creates a new UserAgentTransport with the specified user agent. If no user agent is provided, it uses the default UserAgent() with version information. The transport wraps the provided RoundTripper, defaulting to http.DefaultTransport if nil.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
linters/jsonschema
command
|
|
|
mcp-grafana
command
|
|
|
internal
|
|
|
Package observability provides OpenTelemetry-based metrics and tracing for the MCP Grafana server.
|
Package observability provides OpenTelemetry-based metrics and tracing for the MCP Grafana server. |