Skip to main content
Glama
honeycombio
by honeycombio

list_boards

Retrieve available Honeycomb dashboards for a specific environment with pagination, sorting, and search capabilities to find relevant monitoring boards.

Instructions

Lists available boards (dashboards) for a specific environment with pagination, sorting, and search support. Returns board IDs, names, descriptions, creation times, and last update 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 createListBoardsTool function defines and exports the list_boards tool implementation, including the handler logic that fetches boards via Honeycomb API, handles validation, pagination, sorting, search, caching, and formats the response as JSON.
    export function createListBoardsTool(api: HoneycombAPI) {
      return {
        name: "list_boards",
        description: "Lists available boards (dashboards) for a specific environment with pagination, sorting, and search support. Returns board IDs, names, descriptions, creation times, and last update times.",
        schema: ListBoardsSchema.shape,
        /**
         * Handler for the list_boards 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 boards with relevant metadata, potentially paginated
         */
        handler: async (params: z.infer<typeof ListBoardsSchema>) => {
          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_boards");
          }
    
          try {
            // Fetch boards from the API
            const boards = await api.getBoards(environment);
            
            // Safety check - ensure boards is an array
            if (!Array.isArray(boards)) {
              return {
                content: [
                  {
                    type: "text",
                    text: JSON.stringify([], null, 2),
                  },
                ],
                metadata: {
                  count: 0,
                  environment
                }
              };
            }
            
            // Create a simplified response, with additional error handling
            const simplifiedBoards = boards.map(board => {
              // Create a copy with defaults for missing fields
              return {
                id: board.id || 'unknown-id',
                name: board.name || 'Unnamed Board',
                description: board.description || '',
                created_at: board.created_at || new Date().toISOString(),
                updated_at: board.updated_at || new Date().toISOString(),
              };
            });
            
            // If no pagination or filtering is requested, return all boards
            if (!page && !limit && !search && !sort_by) {
              return {
                content: [
                  {
                    type: "text",
                    text: JSON.stringify(simplifiedBoards, null, 2),
                  },
                ],
                metadata: {
                  count: simplifiedBoards.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 || ['name', 'description'],
                  term: search,
                  caseInsensitive: true
                }
              })
            };
            
            // Access the collection with pagination and filtering
            const result = cache.accessCollection(
              environment, 
              'board', 
              undefined, 
              cacheOptions
            );
            
            // If the collection isn't in cache yet, apply the filtering manually
            if (!result) {
              // Basic implementation for non-cached data
              let filteredBoards = [...simplifiedBoards];
              
              // Apply search if requested
              if (search) {
                const searchFields = Array.isArray(search_fields) 
                  ? search_fields 
                  : search_fields 
                    ? [search_fields] 
                    : ['name', 'description'];
                    
                const searchTerm = search.toLowerCase();
                
                filteredBoards = filteredBoards.filter(board => {
                  return searchFields.some(field => {
                    const value = board[field as keyof typeof board];
                    return typeof value === 'string' && value.toLowerCase().includes(searchTerm);
                  });
                });
              }
              
              // Apply sorting if requested
              if (sort_by) {
                const field = sort_by;
                const order = sort_order || 'asc';
                
                filteredBoards.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 = filteredBoards.length;
              const pages = Math.ceil(total / itemLimit);
              const offset = (currentPage - 1) * itemLimit;
              
              // Return formatted response
              const paginatedResponse: PaginatedResponse<typeof simplifiedBoards[0]> = {
                data: filteredBoards.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 simplifiedBoards;
            
            const paginatedResponse: PaginatedResponse<typeof simplifiedBoards[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_boards");
          }
        }
      };
    }
  • Zod schema defining input parameters for the list_boards tool: environment (required) merged with PaginationSchema for optional pagination, sorting, and search options.
    export const ListBoardsSchema = z.object({
      environment: z.string().min(1).trim().describe("The Honeycomb environment"),
    }).merge(PaginationSchema).describe("Parameters for listing Honeycomb boards. Returns a paginated list of boards with metadata.");
  • Imports the createListBoardsTool function and includes it in the tools array passed to registerTools, which registers all tools with the MCP server by calling server.tool() for each.
    import { createListBoardsTool } from "./list-boards.js";
    import { createGetBoardTool } from "./get-board.js";
    import { createListMarkersTool } from "./list-markers.js";
    import { createListRecipientsTool } from "./list-recipients.js";
    import { createListSLOsTool } from "./list-slos.js";
    import { createGetSLOTool } from "./get-slo.js";
    import { createListTriggersTool } from "./list-triggers.js";
    import { createGetTriggerTool } from "./get-trigger.js";
    import { createTraceDeepLinkTool } from "./get-trace-link.js";
    import { createInstrumentationGuidanceTool } from "./instrumentation-guidance.js";
    import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
    import { z } from "zod";
    
    /**
     * Register all tools with the MCP server
     * 
     * @param server - The MCP server instance
     * @param api - The Honeycomb API client
     */
    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),
Behavior3/5

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

With no annotations provided, the description carries full burden. It discloses key behavioral traits: pagination support, sorting capabilities, search functionality, and the return data structure (board IDs, names, descriptions, creation/update times). However, it doesn't mention rate limits, authentication requirements, error conditions, or whether this is a read-only operation (though 'Lists' implies safe read).

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?

Two tightly constructed sentences with zero waste. The first sentence establishes purpose and key capabilities; the second specifies return values. Every element serves a clear purpose, and the description is appropriately sized for a list operation with multiple parameters.

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

Completeness4/5

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

For a list operation with 7 parameters (1 required) and no output schema, the description provides good context: purpose, capabilities, and return structure. However, without annotations or output schema, it could benefit from mentioning authentication requirements, rate limits, or error handling. The completeness is strong but not perfect given the parameter complexity.

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 7 parameters thoroughly. The description adds context about what the tool does with these parameters ('with pagination, sorting, and search support'), but doesn't provide additional semantic details beyond what's in the schema descriptions. This meets the baseline for high schema coverage.

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

Purpose5/5

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

The description clearly states the verb ('Lists') and resource ('available boards/dashboards') with specific scope ('for a specific environment'). It distinguishes from siblings like get_board (singular retrieval) and list_datasets/list_columns (different resources). The mention of pagination, sorting, and search further clarifies functionality beyond basic listing.

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

Usage Guidelines3/5

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

The description implies usage context through 'for a specific environment' and mentions pagination/sorting/search capabilities, suggesting when these features are needed. However, it doesn't explicitly state when to use this tool versus alternatives like get_board (for single board details) or other list_* tools for different resource types. No explicit exclusions or prerequisites are provided.

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