Skip to main content
Glama
milkosten

Task API Server

by milkosten

listTasks

Retrieve and filter tasks by status or priority to manage workloads efficiently using the Task API Server.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
statusNoFilter tasks by status (optional)
priorityNoFilter tasks by priority level (optional)

Implementation Reference

  • Handler function for listTasks tool: fetches tasks from external API with optional status and priority filters, handles various response formats, formats tasks, and returns formatted list or error.
    async ({ status, priority }: { status?: string, priority?: string }) => {
      try {
        const params: any = {};
        if (status) params.status = status;
        if (priority) params.priority = priority;
    
        const tasksResponse = await makeApiRequest("POST", "/tasks/list", { status, priority });
        
        // More flexible validation for tasks data structure
        let tasks: any[] = [];
        
        // Handle various response formats that might come from the API
        if (tasksResponse) {
          if (Array.isArray(tasksResponse.tasks)) {
            // Standard format: { tasks: [...] }
            tasks = tasksResponse.tasks;
            logDebug("Found tasks array in standard format");
          } else if (Array.isArray(tasksResponse)) {
            // Direct array format: [...]
            tasks = tasksResponse;
            logDebug("Found tasks in direct array format");
          } else if (typeof tasksResponse === 'object' && tasksResponse !== null) {
            // Try to extract tasks from any available property
            const possibleTasksProperties = Object.entries(tasksResponse)
              .filter(([_, value]) => Array.isArray(value))
              .map(([key, value]) => ({ key, value }));
              
            if (possibleTasksProperties.length > 0) {
              // Use the first array property as tasks
              const tasksProp = possibleTasksProperties[0];
              tasks = tasksProp.value as any[];
              logDebug(`Found tasks array in property: ${tasksProp.key}`);
            } else {
              logError(`No tasks array found in response`, tasksResponse);
            }
          }
        }
        
        // If we still couldn't find tasks, log error and return empty array
        if (tasks.length === 0) {
          logError(`Invalid or empty tasks data structure`, tasksResponse);
        }
        
        // Format response in a way that's useful for AI to parse
        const formattedTasks = tasks.map(task => ({
          id: task.id,
          task: task.task || "No description",
          category: task.category,
          priority: task.priority || "medium",
          status: task.status || "not_started",
          createTime: task.create_time || task.created_at || task.createTime || new Date().toISOString()
        }));
        
        // Log the formatted response for debugging
        logDebug(`listTasks formatted response`, formattedTasks);
    
        return {
          content: [
            {
              type: "text",
              text: `Found ${tasks.length} tasks${status ? ` with status '${status}'` : ''}${priority ? ` and priority '${priority}'` : ''}.`
            },
            {
              type: "text",
              text: JSON.stringify(formattedTasks, null, 2)
            }
          ]
        };
      } catch (error: any) {
        return {
          content: [
            {
              type: "text",
              text: `Error listing tasks: ${error.message}`
            }
          ]
        };
      }
    }
  • Input schema for listTasks tool, defining optional status and priority parameters using Zod.
    { 
      status: z.enum(["not_started", "started", "done"]).optional()
        .describe("Filter tasks by status (optional)"),
      priority: z.enum(["low", "medium", "high"]).optional()
        .describe("Filter tasks by priority level (optional)")
    }, 
  • src/index.ts:282-369 (registration)
    Registration of the listTasks tool on the MCP server, including name, input schema, and handler function.
    server.tool(
      "listTasks", 
      { 
        status: z.enum(["not_started", "started", "done"]).optional()
          .describe("Filter tasks by status (optional)"),
        priority: z.enum(["low", "medium", "high"]).optional()
          .describe("Filter tasks by priority level (optional)")
      }, 
      async ({ status, priority }: { status?: string, priority?: string }) => {
        try {
          const params: any = {};
          if (status) params.status = status;
          if (priority) params.priority = priority;
    
          const tasksResponse = await makeApiRequest("POST", "/tasks/list", { status, priority });
          
          // More flexible validation for tasks data structure
          let tasks: any[] = [];
          
          // Handle various response formats that might come from the API
          if (tasksResponse) {
            if (Array.isArray(tasksResponse.tasks)) {
              // Standard format: { tasks: [...] }
              tasks = tasksResponse.tasks;
              logDebug("Found tasks array in standard format");
            } else if (Array.isArray(tasksResponse)) {
              // Direct array format: [...]
              tasks = tasksResponse;
              logDebug("Found tasks in direct array format");
            } else if (typeof tasksResponse === 'object' && tasksResponse !== null) {
              // Try to extract tasks from any available property
              const possibleTasksProperties = Object.entries(tasksResponse)
                .filter(([_, value]) => Array.isArray(value))
                .map(([key, value]) => ({ key, value }));
                
              if (possibleTasksProperties.length > 0) {
                // Use the first array property as tasks
                const tasksProp = possibleTasksProperties[0];
                tasks = tasksProp.value as any[];
                logDebug(`Found tasks array in property: ${tasksProp.key}`);
              } else {
                logError(`No tasks array found in response`, tasksResponse);
              }
            }
          }
          
          // If we still couldn't find tasks, log error and return empty array
          if (tasks.length === 0) {
            logError(`Invalid or empty tasks data structure`, tasksResponse);
          }
          
          // Format response in a way that's useful for AI to parse
          const formattedTasks = tasks.map(task => ({
            id: task.id,
            task: task.task || "No description",
            category: task.category,
            priority: task.priority || "medium",
            status: task.status || "not_started",
            createTime: task.create_time || task.created_at || task.createTime || new Date().toISOString()
          }));
          
          // Log the formatted response for debugging
          logDebug(`listTasks formatted response`, formattedTasks);
    
          return {
            content: [
              {
                type: "text",
                text: `Found ${tasks.length} tasks${status ? ` with status '${status}'` : ''}${priority ? ` and priority '${priority}'` : ''}.`
              },
              {
                type: "text",
                text: JSON.stringify(formattedTasks, null, 2)
              }
            ]
          };
        } catch (error: any) {
          return {
            content: [
              {
                type: "text",
                text: `Error listing tasks: ${error.message}`
              }
            ]
          };
        }
      }
    );
  • Handler function for listTasks tool (duplicate implementation in HTTP server version): fetches tasks from external API with optional filters, handles response formats, formats and returns task list.
    async ({ status, priority }: { status?: string, priority?: string }) => {
      try {
        const params: any = {};
        if (status) params.status = status;
        if (priority) params.priority = priority;
    
        const tasksResponse = await makeApiRequest("POST", "/tasks/list", { status, priority });
        
        // More flexible validation for tasks data structure
        let tasks: any[] = [];
        
        // Handle various response formats that might come from the API
        if (tasksResponse) {
          if (Array.isArray(tasksResponse.tasks)) {
            // Standard format: { tasks: [...] }
            tasks = tasksResponse.tasks;
            logDebug("Found tasks array in standard format");
          } else if (Array.isArray(tasksResponse)) {
            // Direct array format: [...]
            tasks = tasksResponse;
            logDebug("Found tasks in direct array format");
          } else if (typeof tasksResponse === 'object' && tasksResponse !== null) {
            // Try to extract tasks from any available property
            const possibleTasksProperties = Object.entries(tasksResponse)
              .filter(([_, value]) => Array.isArray(value))
              .map(([key, value]) => ({ key, value }));
              
            if (possibleTasksProperties.length > 0) {
              // Use the first array property as tasks
              const tasksProp = possibleTasksProperties[0];
              tasks = tasksProp.value as any[];
              logDebug(`Found tasks array in property: ${tasksProp.key}`);
            } else {
              logError(`No tasks array found in response`, tasksResponse);
            }
          }
        }
        
        // If we still couldn't find tasks, log error and return empty array
        if (tasks.length === 0) {
          logError(`Invalid or empty tasks data structure`, tasksResponse);
        }
        
        // Format response in a way that's useful for AI to parse
        const formattedTasks = tasks.map(task => ({
          id: task.id,
          task: task.task || "No description",
          category: task.category,
          priority: task.priority || "medium",
          status: task.status || "not_started",
          createTime: task.create_time || task.created_at || task.createTime || new Date().toISOString()
        }));
        
        // Log the formatted response for debugging
        logDebug(`listTasks formatted response`, formattedTasks);
    
        return {
          content: [
            {
              type: "text",
              text: `Found ${tasks.length} tasks${status ? ` with status '${status}'` : ''}${priority ? ` and priority '${priority}'` : ''}.`
            },
            {
              type: "text",
              text: JSON.stringify(formattedTasks, null, 2)
            }
          ]
        };
      } catch (error: any) {
        return {
          content: [
            {
              type: "text",
              text: `Error listing tasks: ${error.message}`
            }
          ]
        };
      }
    }
  • Input schema for listTasks tool (HTTP server version), defining optional status and priority filters using Zod.
    { 
      status: z.enum(["not_started", "started", "done"]).optional()
        .describe("Filter tasks by status (optional)"),
      priority: z.enum(["low", "medium", "high"]).optional()
        .describe("Filter tasks by priority level (optional)")
    }, 
Behavior1/5

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

Tool has no description.

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

Conciseness1/5

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

Tool has no description.

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

Completeness1/5

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

Tool has no description.

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

Parameters1/5

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

Tool has no description.

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

Purpose1/5

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

Tool has no description.

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

Usage Guidelines1/5

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

Tool has no description.

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/milkosten/task-mcp-server'

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