Skip to main content
Glama
0xteamhq

Grafana MCP Server

by 0xteamhq

generate_deeplink

Create direct links to Grafana dashboards, panels, and Explore queries with custom time ranges and parameters for easy sharing and access.

Instructions

Generate deeplink URLs for Grafana resources. Supports dashboards, panels, and Explore queries

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
dashboardUidNoDashboard UID (required for dashboard and panel types)
datasourceUidNoDatasource UID (required for explore type)
panelIdNoPanel ID (required for panel type)
queryParamsNoAdditional query parameters
resourceTypeYesType of resource
timeRangeNoTime range for the link

Implementation Reference

  • The core handler function for the 'generate_deeplink' tool that constructs Grafana deeplink URLs for dashboards, panels, or explore views based on input parameters, time range, and query params using the Grafana base URL from context.
    handler: async (params, context: ToolContext) => {
      try {
        const baseUrl = context.config.grafanaConfig.url;
        let url = '';
        const queryParams = new URLSearchParams();
        
        // Add time range if provided
        if (params.timeRange) {
          queryParams.append('from', params.timeRange.from);
          queryParams.append('to', params.timeRange.to);
        }
        
        // Add additional query params
        if (params.queryParams) {
          Object.entries(params.queryParams).forEach(([key, value]) => {
            queryParams.append(key, String(value));
          });
        }
        
        switch (params.resourceType) {
          case 'dashboard':
            if (!params.dashboardUid) {
              return createErrorResult('dashboardUid is required for dashboard type');
            }
            url = `${baseUrl}/d/${params.dashboardUid}`;
            break;
            
          case 'panel':
            if (!params.dashboardUid || params.panelId === undefined) {
              return createErrorResult('dashboardUid and panelId are required for panel type');
            }
            url = `${baseUrl}/d/${params.dashboardUid}`;
            queryParams.append('viewPanel', params.panelId.toString());
            break;
            
          case 'explore':
            if (!params.datasourceUid) {
              return createErrorResult('datasourceUid is required for explore type');
            }
            url = `${baseUrl}/explore`;
            queryParams.append('left', JSON.stringify({
              datasource: params.datasourceUid,
              queries: [],
              range: params.timeRange || { from: 'now-1h', to: 'now' },
            }));
            break;
            
          default:
            return createErrorResult(`Unknown resource type: ${params.resourceType}`);
        }
        
        // Append query params to URL
        const queryString = queryParams.toString();
        if (queryString) {
          url += `?${queryString}`;
        }
        
        return createToolResult({ url });
      } catch (error: any) {
        return createErrorResult(error.message);
      }
    },
  • Zod input schema defining parameters for the generate_deeplink tool, including resource type, UIDs, time range, and query params.
    const GenerateDeeplinkSchema = z.object({
      resourceType: z.enum(['dashboard', 'panel', 'explore']).describe('Type of resource'),
      dashboardUid: z.string().optional().describe('Dashboard UID (required for dashboard and panel types)'),
      panelId: z.number().optional().describe('Panel ID (required for panel type)'),
      datasourceUid: z.string().optional().describe('Datasource UID (required for explore type)'),
      timeRange: z.object({
        from: z.string().describe('Start time (e.g., "now-1h")'),
        to: z.string().describe('End time (e.g., "now")'),
      }).optional().describe('Time range for the link'),
      queryParams: z.record(z.string()).optional().describe('Additional query parameters'),
    });
  • Registration function for navigation tools that directly registers the generate_deeplink tool with the MCP server.
    export function registerNavigationTools(server: any) {
      server.registerTool(generateDeeplink);
    }
  • src/cli.ts:131-133 (registration)
    Main entrypoint call to register navigation tools (including generate_deeplink) conditionally if the 'navigation' tool category is enabled.
    if (enabledTools.has('navigation')) {
      registerNavigationTools(server);
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states what the tool does but doesn't describe important behavioral aspects: whether this is a read-only operation, what permissions are required, how the generated URLs are formatted, if there are rate limits, or what happens with invalid inputs. For a tool that generates URLs (likely a safe operation), more context would be helpful.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is perfectly concise - a single sentence that efficiently communicates the core functionality and supported resource types. Every word earns its place with zero waste. It's appropriately sized for a tool with good schema documentation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (6 parameters including nested objects) and 100% schema coverage but no annotations or output schema, the description is minimally adequate. It states what the tool does but lacks context about the generated URLs' format, use cases, or integration with other tools. For a URL generation tool with no output schema, some description of the return value would be beneficial.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 6 parameters thoroughly. The description adds minimal value beyond the schema by mentioning the three resource types (dashboard, panel, explore) which are already in the resourceType enum. It doesn't provide additional context about parameter interactions or usage patterns beyond what's in the schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Generate deeplink URLs for Grafana resources' with specific resource types listed (dashboards, panels, Explore queries). It uses a specific verb ('generate') and identifies the resource ('deeplink URLs'), but doesn't explicitly differentiate from sibling tools, which are mostly query/retrieval operations rather than URL generation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It mentions supported resource types but doesn't indicate scenarios where generating deeplinks is appropriate compared to other tools like 'get_dashboard_by_uid' or 'search_dashboards'. There's no mention of prerequisites, constraints, or typical use cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/0xteamhq/mcp-grafana'

If you have feedback or need assistance with the MCP directory API, please join our Discord server