Skip to main content
Glama

backlog_list

List and filter backlog tasks by status, type, or search query to manage work items and track progress with customizable limits.

Instructions

List tasks from backlog. Returns most recently updated items first. Default: shows only active work (open/in_progress/blocked), limited to 20 items. Use counts=true to check if more items exist beyond the limit.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
statusNoFilter by status. Options: open, in_progress, blocked, done, cancelled. Default: [open, in_progress, blocked]. Pass ["done"] to see completed work.
typeNoFilter by type. Options: task, epic, folder, artifact, milestone. Default: returns all.
epic_idNoFilter tasks belonging to a specific epic. Example: epic_id="EPIC-0001"
parent_idNoFilter items by parent. Example: parent_id="FLDR-0001"
queryNoSearch across all task fields (title, description, evidence, references, etc.). Case-insensitive substring matching.
countsNoInclude global counts { total_tasks, total_epics, by_status, by_type } alongside results. Use this to detect if more items exist beyond the limit. Default: false
limitNoMax items to return. Default: 20. Increase if you need to see more items (e.g., limit=100 to list all epics).

Implementation Reference

  • Main handler function that executes the backlog_list tool logic. It filters tasks by status, type, epic_id, parent_id, and query parameters, then formats the results with optional counts.
    async ({ status, type, epic_id, parent_id, query, counts, limit }) => {
      // parent_id takes precedence; epic_id is alias for backward compat
      const resolvedParent = parent_id ?? epic_id;
      const tasks = await storage.list({ status, type, parent_id: resolvedParent, query, limit });
      const list = tasks.map((t) => ({
        id: t.id,
        title: t.title,
        status: t.status,
        type: t.type ?? 'task',
        parent_id: t.parent_id ?? t.epic_id,
      }));
      const result: any = { tasks: list };
      if (counts) result.counts = storage.counts();
      return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
    }
  • Zod input schema defining all filter parameters for backlog_list: status array, type enum, epic_id, parent_id, query string, counts boolean, and limit number.
    inputSchema: z.object({
      status: z.array(z.enum(STATUSES)).optional().describe('Filter by status. Options: open, in_progress, blocked, done, cancelled. Default: [open, in_progress, blocked]. Pass ["done"] to see completed work.'),
      type: z.enum(ENTITY_TYPES).optional().describe('Filter by type. Options: task, epic, folder, artifact, milestone. Default: returns all.'),
      epic_id: z.string().optional().describe('Filter tasks belonging to a specific epic. Example: epic_id="EPIC-0001"'),
      parent_id: z.string().optional().describe('Filter items by parent. Example: parent_id="FLDR-0001"'),
      query: z.string().optional().describe('Search across all task fields (title, description, evidence, references, etc.). Case-insensitive substring matching.'),
      counts: z.boolean().optional().describe('Include global counts { total_tasks, total_epics, by_status, by_type } alongside results. Use this to detect if more items exist beyond the limit. Default: false'),
      limit: z.number().optional().describe('Max items to return. Default: 20. Increase if you need to see more items (e.g., limit=100 to list all epics).'),
    }),
  • Tool registration function that registers 'backlog_list' with the MCP server, including the tool description and input schema.
    export function registerBacklogListTool(server: McpServer) {
      server.registerTool(
        'backlog_list',
        {
          description: 'List tasks from backlog. Returns most recently updated items first. Default: shows only active work (open/in_progress/blocked), limited to 20 items. Use counts=true to check if more items exist beyond the limit.',
          inputSchema: z.object({
            status: z.array(z.enum(STATUSES)).optional().describe('Filter by status. Options: open, in_progress, blocked, done, cancelled. Default: [open, in_progress, blocked]. Pass ["done"] to see completed work.'),
            type: z.enum(ENTITY_TYPES).optional().describe('Filter by type. Options: task, epic, folder, artifact, milestone. Default: returns all.'),
            epic_id: z.string().optional().describe('Filter tasks belonging to a specific epic. Example: epic_id="EPIC-0001"'),
            parent_id: z.string().optional().describe('Filter items by parent. Example: parent_id="FLDR-0001"'),
            query: z.string().optional().describe('Search across all task fields (title, description, evidence, references, etc.). Case-insensitive substring matching.'),
            counts: z.boolean().optional().describe('Include global counts { total_tasks, total_epics, by_status, by_type } alongside results. Use this to detect if more items exist beyond the limit. Default: false'),
            limit: z.number().optional().describe('Max items to return. Default: 20. Increase if you need to see more items (e.g., limit=100 to list all epics).'),
          }),
        },
  • Storage service list method that handles the actual data retrieval, including both search-based and filter-based listing of entities.
    async list(filter?: { status?: Status[]; type?: EntityType; epic_id?: string; parent_id?: string; query?: string; limit?: number }): Promise<Entity[]> {
      const { query, ...storageFilter } = filter ?? {};
    
      if (query) {
        await this.ensureSearchReady();
        const results = await this.search.search(query, {
          filters: { status: storageFilter.status, type: storageFilter.type, epic_id: storageFilter.epic_id, parent_id: storageFilter.parent_id },
          limit: storageFilter.limit,
        });
        return results.map(r => ({ ...r.task, score: r.score }));
      }
    
      return this.taskStorage.list(storageFilter);
    }
  • Schema constants defining EntityType enum, ENTITY_TYPES array, and STATUSES array used as validation enums in backlog_list input schema.
    export enum EntityType {
      Task = 'task',
      Epic = 'epic',
      Folder = 'folder',
      Artifact = 'artifact',
      Milestone = 'milestone',
    }
    
    export const ENTITY_TYPES = Object.values(EntityType);
    
    export const TYPE_PREFIXES: Record<EntityType, string> = {
      [EntityType.Task]: 'TASK',
      [EntityType.Epic]: 'EPIC',
      [EntityType.Folder]: 'FLDR',
      [EntityType.Artifact]: 'ARTF',
      [EntityType.Milestone]: 'MLST',
    };
    
    const PREFIX_TO_TYPE: Record<string, EntityType> = Object.fromEntries(
      Object.entries(TYPE_PREFIXES).map(([type, prefix]) => [prefix, type as EntityType]),
    ) as Record<string, EntityType>;
    
    // ============================================================================
    // Status
    // ============================================================================
    
    export const STATUSES = ['open', 'in_progress', 'blocked', 'done', 'cancelled'] as const;
    export type Status = (typeof STATUSES)[number];

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/gkoreli/backlog-mcp'

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