Skip to main content
Glama
honeycombio
by honeycombio

list_markers

Retrieve deployment events from Honeycomb datasets with pagination, sorting, and search capabilities to monitor environment changes.

Instructions

Lists available markers (deployment events) for a specific dataset or environment with pagination, sorting, and search support. Returns IDs, messages, types, URLs, creation times, start times, and end times.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
environmentYesThe Honeycomb environment
pageNoPage number (1-based)
limitNoNumber of items per page
sort_byNoField to sort by
sort_orderNoSort direction
searchNoSearch term to filter results
search_fieldsNoFields to search in (string or array of strings)

Implementation Reference

  • The createListMarkersTool function that constructs the MCP tool object for 'list_markers', including the core handler logic that fetches markers from the Honeycomb API, processes them (simplification, pagination, sorting, filtering, caching), and formats the response.
    export function createListMarkersTool(api: HoneycombAPI) {
      return {
        name: "list_markers",
        description: "Lists available markers (deployment events) for a specific dataset or environment with pagination, sorting, and search support. Returns IDs, messages, types, URLs, creation times, start times, and end times.",
        schema: ListMarkersSchema.shape,
        /**
         * Handler for the list_markers tool
         * 
         * @param params - The parameters for the tool
         * @param params.environment - The Honeycomb environment
         * @param params.page - Optional page number for pagination
         * @param params.limit - Optional limit of items per page
         * @param params.sort_by - Optional field to sort by
         * @param params.sort_order - Optional sort direction (asc/desc)
         * @param params.search - Optional search term
         * @param params.search_fields - Optional fields to search in
         * @returns List of markers with relevant metadata, potentially paginated
         */
        handler: async (params: z.infer<typeof ListMarkersSchema>) => {
          const { environment, page, limit, sort_by, sort_order, search, search_fields } = params;
          
          // Validate input parameters
          if (!environment) {
            return handleToolError(new Error("environment parameter is required"), "list_markers");
          }
    
          try {
            // Fetch markers from the API
            const markers = await api.getMarkers(environment);
            
            // Create a simplified response
            const simplifiedMarkers = markers.map(marker => ({
              id: marker.id,
              message: marker.message,
              type: marker.type,
              url: marker.url || '',
              created_at: marker.created_at,
              start_time: marker.start_time,
              end_time: marker.end_time || '',
            }));
            
            // If no pagination or filtering is requested, return all markers
            if (!page && !limit && !search && !sort_by) {
              return {
                content: [
                  {
                    type: "text",
                    text: JSON.stringify(simplifiedMarkers, null, 2),
                  },
                ],
                metadata: {
                  count: simplifiedMarkers.length,
                  environment
                }
              };
            }
            
            // Otherwise, use the cache manager to handle pagination, sorting, and filtering
            const cache = getCache();
            const cacheOptions = {
              page: page || 1,
              limit: limit || 10,
              
              // Configure sorting if requested
              ...(sort_by && {
                sort: {
                  field: sort_by,
                  order: sort_order || 'asc'
                }
              }),
              
              // Configure search if requested
              ...(search && {
                search: {
                  field: search_fields || ['message', 'type'],
                  term: search,
                  caseInsensitive: true
                }
              })
            };
            
            // Access the collection with pagination and filtering
            const result = cache.accessCollection(
              environment, 
              'marker', 
              undefined, 
              cacheOptions
            );
            
            // If the collection isn't in cache yet, apply the filtering manually
            if (!result) {
              // Basic implementation for non-cached data
              let filteredMarkers = [...simplifiedMarkers];
              
              // Apply search if requested
              if (search) {
                const searchFields = Array.isArray(search_fields) 
                  ? search_fields 
                  : search_fields 
                    ? [search_fields] 
                    : ['message', 'type'];
                    
                const searchTerm = search.toLowerCase();
                
                filteredMarkers = filteredMarkers.filter(marker => {
                  return searchFields.some(field => {
                    const value = marker[field as keyof typeof marker];
                    return typeof value === 'string' && value.toLowerCase().includes(searchTerm);
                  });
                });
              }
              
              // Apply sorting if requested
              if (sort_by) {
                const field = sort_by;
                const order = sort_order || 'asc';
                
                filteredMarkers.sort((a, b) => {
                  const aValue = a[field as keyof typeof a];
                  const bValue = b[field as keyof typeof b];
                  
                  if (typeof aValue === 'string' && typeof bValue === 'string') {
                    return order === 'asc' 
                      ? aValue.localeCompare(bValue) 
                      : bValue.localeCompare(aValue);
                  }
                  
                  return order === 'asc' 
                    ? (aValue > bValue ? 1 : -1) 
                    : (bValue > aValue ? 1 : -1);
                });
              }
              
              // Apply pagination
              const itemLimit = limit || 10;
              const currentPage = page || 1;
              const total = filteredMarkers.length;
              const pages = Math.ceil(total / itemLimit);
              const offset = (currentPage - 1) * itemLimit;
              
              // Return formatted response
              const paginatedResponse: PaginatedResponse<typeof simplifiedMarkers[0]> = {
                data: filteredMarkers.slice(offset, offset + itemLimit),
                metadata: {
                  total,
                  page: currentPage,
                  pages,
                  limit: itemLimit
                }
              };
              
              return {
                content: [
                  {
                    type: "text",
                    text: JSON.stringify(paginatedResponse, null, 2),
                  },
                ],
              };
            }
            
            // Format the cached result and type-cast the unknown data
            const typedData = result.data as typeof simplifiedMarkers;
            
            const paginatedResponse: PaginatedResponse<typeof simplifiedMarkers[0]> = {
              data: typedData,
              metadata: {
                total: result.total,
                page: result.page || 1,
                pages: result.pages || 1,
                limit: limit || 10
              }
            };
            
            return {
              content: [
                {
                  type: "text",
                  text: JSON.stringify(paginatedResponse, null, 2),
                },
              ],
            };
          } catch (error) {
            return handleToolError(error, "list_markers");
          }
        }
      };
    }
  • Zod schema for the list_markers tool input parameters: requires 'environment', optionally merges PaginationSchema for page, limit, sort_by, sort_order, search, search_fields.
    export const ListMarkersSchema = z.object({
      environment: z.string().min(1).trim().describe("The Honeycomb environment"),
    }).merge(PaginationSchema).describe("Parameters for listing Honeycomb markers. Markers represent significant events like deployments or incidents.");
  • Call to createListMarkersTool(api) which instantiates the tool and adds it to the array passed to the MCP server registration loop.
    createListMarkersTool(api),
  • src/tools/index.ts:8-8 (registration)
    Import statement for the list_markers tool creator from "./list-markers.js".
    import { createListMarkersTool } from "./list-markers.js";
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 mentions that the tool returns specific fields (IDs, messages, types, etc.) and supports pagination, sorting, and search, but lacks details on permissions, rate limits, error handling, or what happens if parameters are omitted. For a read operation with 7 parameters, this is insufficient.

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

Conciseness4/5

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

The description is concise and front-loaded, stating the core purpose in the first clause. It efficiently lists features and return fields in a single sentence with no wasted words, though it could be slightly more structured for readability.

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 complexity (7 parameters, no output schema, no annotations), the description is moderately complete. It covers the purpose and return fields but lacks behavioral details and usage context. Without an output schema, it should ideally explain the return format more thoroughly, but the listed fields provide some clarity.

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 parameters thoroughly. The description adds minimal value by implying the tool supports pagination, sorting, and search, but doesn't provide additional context beyond what's in the schema. Baseline 3 is appropriate when the schema does the heavy lifting.

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: 'Lists available markers (deployment events) for a specific dataset or environment' with specific functionality like pagination, sorting, and search. It distinguishes itself from siblings like list_datasets or list_boards by focusing on markers/deployment events, though it doesn't explicitly contrast with them.

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 the tool's features but doesn't indicate scenarios where it's appropriate, prerequisites, or how it differs from other list tools in the sibling set.

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

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