Skip to main content
Glama
honeycombio
by honeycombio

get_trace_link

Generate direct deep links to specific Honeycomb traces for quick debugging. Create URLs that open distributed traces with optional span focus and time range targeting.

Instructions

Generates a direct deep link to a specific trace in the Honeycomb UI. This tool creates a URL that opens a specific distributed trace, optionally positioning to a particular span and time range. If no time range is specified, the trace must have been generated within two hours from the current time. If only the start time is provided, the end time is assumed to be 10 minutes from the start time.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
environmentYesThe Honeycomb environment
datasetYesThe dataset containing the trace
traceIdYesThe unique trace ID
spanIdNoThe unique span ID to jump to within the trace
traceStartTsNoStart timestamp in Unix epoch seconds
traceEndTsNoEnd timestamp in Unix epoch seconds

Implementation Reference

  • The main handler function that executes the get_trace_link tool logic: validates inputs, fetches team slug, constructs the Honeycomb trace deep link URL with optional span and time range, and returns formatted response.
    handler: async (params: z.infer<typeof TraceDeepLinkSchema>) => {
      try {
        // Validate required parameters
        if (!params.environment) {
          throw new Error("Missing required parameter: environment");
        }
        if (!params.dataset) {
          throw new Error("Missing required parameter: dataset");
        }
        if (!params.traceId) {
          throw new Error("Missing required parameter: traceId");
        }
    
        // Get the team slug for the environment
        const teamSlug = await api.getTeamSlug(params.environment);
        
        // Start building the trace URL
        let traceUrl = `https://ui.honeycomb.io/${teamSlug}/environments/${params.environment}/trace?trace_id=${encodeURIComponent(params.traceId)}`;
        
        // Add optional parameters if provided
        if (params.spanId) {
          traceUrl += `&span=${encodeURIComponent(params.spanId)}`;
        }
        
        if (params.traceStartTs) {
          traceUrl += `&trace_start_ts=${params.traceStartTs}`;
        }
        
        if (params.traceEndTs) {
          traceUrl += `&trace_end_ts=${params.traceEndTs}`;
        }
        
        // Add dataset parameter for more specific context
        if (params.dataset) {
          // Insert the dataset before the trace part in the URL
          traceUrl = traceUrl.replace(
            `/trace?`,
            `/datasets/${encodeURIComponent(params.dataset)}/trace?`
          );
        }
        
        return {
          content: [
            {
              type: "text",
              text: JSON.stringify({
                url: traceUrl,
                environment: params.environment,
                dataset: params.dataset,
                traceId: params.traceId,
                team: teamSlug
              }, null, 2),
            },
          ],
          metadata: {
            environment: params.environment,
            dataset: params.dataset,
            traceId: params.traceId,
            team: teamSlug
          }
        };
      } catch (error) {
        return handleToolError(error, "get_trace_link");
      }
    }
  • Zod schema defining the input parameters and validation for the get_trace_link tool, including environment, dataset, traceId, optional spanId and timestamps with refinement for timestamp order.
     * Schema for generating a trace deep link
     */
    export const TraceDeepLinkSchema = z.object({
      environment: z.string().min(1).trim().describe("The Honeycomb environment"),
      dataset: z.string().min(1).trim().describe("The dataset containing the trace"),
      traceId: z.string().describe("The unique trace ID"),
      spanId: z.string().optional().describe("The unique span ID to jump to within the trace"),
      traceStartTs: z.number().int().nonnegative().optional().describe("Start timestamp in Unix epoch seconds"),
      traceEndTs: z.number().int().nonnegative().optional().describe("End timestamp in Unix epoch seconds"),
    }).refine(data => {
      // If both timestamps are provided, ensure end > start
      if (data.traceStartTs !== undefined && data.traceEndTs !== undefined) {
        return data.traceEndTs > data.traceStartTs;
      }
      return true;
    }, {
      message: "End timestamp must be greater than start timestamp",
      path: ["traceEndTs"]
    });
  • Factory function that creates the complete MCP tool definition object for 'get_trace_link', including name, description, input schema, and handler function.
    export function createTraceDeepLinkTool(api: HoneycombAPI) {
      return {
        name: "get_trace_link",
        description: "Generates a direct deep link to a specific trace in the Honeycomb UI. This tool creates a URL that opens a specific distributed trace, optionally positioning to a particular span and time range. If no time range is specified, the trace must have been generated within two hours from the current time. If only the start time is provided, the end time is assumed to be 10 minutes from the start time.",
        schema: {
          environment: z.string().min(1).trim().describe("The Honeycomb environment"),
          dataset: z.string().min(1).trim().describe("The dataset containing the trace"),
          traceId: z.string().describe("The unique trace ID"),
          spanId: z.string().optional().describe("The unique span ID to jump to within the trace"),
          traceStartTs: z.number().int().nonnegative().optional().describe("Start timestamp in Unix epoch seconds"),
          traceEndTs: z.number().int().nonnegative().optional().describe("End timestamp in Unix epoch seconds")
        },
        /**
         * Handler for the get_trace_link tool
         * 
         * @param params - The parameters for the tool
         * @returns A URL for direct access to the trace in the Honeycomb UI
         */
        handler: async (params: z.infer<typeof TraceDeepLinkSchema>) => {
          try {
            // Validate required parameters
            if (!params.environment) {
              throw new Error("Missing required parameter: environment");
            }
            if (!params.dataset) {
              throw new Error("Missing required parameter: dataset");
            }
            if (!params.traceId) {
              throw new Error("Missing required parameter: traceId");
            }
    
            // Get the team slug for the environment
            const teamSlug = await api.getTeamSlug(params.environment);
            
            // Start building the trace URL
            let traceUrl = `https://ui.honeycomb.io/${teamSlug}/environments/${params.environment}/trace?trace_id=${encodeURIComponent(params.traceId)}`;
            
            // Add optional parameters if provided
            if (params.spanId) {
              traceUrl += `&span=${encodeURIComponent(params.spanId)}`;
            }
            
            if (params.traceStartTs) {
              traceUrl += `&trace_start_ts=${params.traceStartTs}`;
            }
            
            if (params.traceEndTs) {
              traceUrl += `&trace_end_ts=${params.traceEndTs}`;
            }
            
            // Add dataset parameter for more specific context
            if (params.dataset) {
              // Insert the dataset before the trace part in the URL
              traceUrl = traceUrl.replace(
                `/trace?`,
                `/datasets/${encodeURIComponent(params.dataset)}/trace?`
              );
            }
            
            return {
              content: [
                {
                  type: "text",
                  text: JSON.stringify({
                    url: traceUrl,
                    environment: params.environment,
                    dataset: params.dataset,
                    traceId: params.traceId,
                    team: teamSlug
                  }, null, 2),
                },
              ],
              metadata: {
                environment: params.environment,
                dataset: params.dataset,
                traceId: params.traceId,
                team: teamSlug
              }
            };
          } catch (error) {
            return handleToolError(error, "get_trace_link");
          }
        }
      };
    }
  • The registerTools function that instantiates the get_trace_link tool via createTraceDeepLinkTool(api) and registers it (along with others) to the MCP server using a generic wrapper handler.
    export function registerTools(server: McpServer, api: HoneycombAPI) {
      const tools = [
        // Dataset tools
        createListDatasetsTool(api),
        createListColumnsTool(api),
    
        // Query tools
        createRunQueryTool(api),
        createAnalyzeColumnsTool(api),
    
        // Board tools
        createListBoardsTool(api),
        createGetBoardTool(api),
    
        // Marker tools
        createListMarkersTool(api),
    
        // Recipient tools
        createListRecipientsTool(api),
    
        // SLO tools
        createListSLOsTool(api),
        createGetSLOTool(api),
    
        // Trigger tools
        createListTriggersTool(api),
        createGetTriggerTool(api),
        
        // Trace tools
        createTraceDeepLinkTool(api),
        
        // Instrumentation tools
        createInstrumentationGuidanceTool(api)
      ];
    
      // Register each tool with the server
      for (const tool of tools) {
        // Register the tool with the server using type assertion to bypass TypeScript's strict type checking
        (server as any).tool(
          tool.name,
          tool.description,
          tool.schema, 
          async (args: Record<string, any>, extra: any) => {
            try {
              // Validate and ensure required fields are present before passing to handler
              if (tool.name.includes("analyze_columns") && (!args.environment || !args.dataset || !args.columns)) {
                throw new Error("Missing required fields: environment, dataset, and columns are required");
              } else if (tool.name.includes("run_query") && (!args.environment || !args.dataset)) {
                throw new Error("Missing required fields: environment and dataset are required");
              }
              
              // Use type assertion to satisfy TypeScript's type checking
              const result = await tool.handler(args as any);
              
              // If the result already has the expected format, return it directly
              if (result && typeof result === 'object' && 'content' in result) {
                return result as any;
              }
              
              // Otherwise, format the result as expected by the SDK
              return {
                content: [
                  {
                    type: "text",
                    text: typeof result === 'string' ? result : JSON.stringify(result, null, 2),
                  },
                ],
              } as any;
            } catch (error) {
              // Format errors to match the SDK's expected format
              return {
                content: [
                  {
                    type: "text",
                    text: error instanceof Error ? error.message : String(error),
                  },
                ],
                isError: true,
              } as any;
            }
          }
        );
      }
    }

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/honeycombio/honeycomb-mcp'

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