Skip to main content
Glama
kydycode

Enhanced Todoist MCP Server Extended

todoist_search_tasks

Search for Todoist tasks by content or name when you don't know the task ID. Filter results by project and limit the number of matches.

Instructions

Search for tasks by content/name (fallback for when ID is not known)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query to find tasks by content
projectIdNoLimit search to specific project (optional)
limitNoMaximum number of results (default: 10) (optional)

Implementation Reference

  • The core handler logic for executing the todoist_search_tasks tool. It validates arguments, constructs a Todoist filter query prefixed with 'search:', calls todoistClient.getTasksByFilter, fetches project details for each task, formats the output using formatTask, and returns a rich text response with pagination info if available.
    if (name === "todoist_search_tasks") { if (!isSearchTasksArgs(args)) { throw new Error("Invalid arguments for todoist_search_tasks"); } // Prepare arguments for getTasksByFilter // Prepend "search: " to the query for more robust keyword searching with Todoist API const searchQuery = args.query.startsWith("search:") ? args.query : `search: ${args.query}`; const filterArgs: any = { query: searchQuery }; if (args.limit) filterArgs.limit = args.limit; // Note: args.projectId is not directly used by getTasksByFilter unless incorporated into the query string. // For example: `search: ${args.query} & #ProjectName` or `search: ${args.query} & ##ProjectID` const tasksResponse = await todoistClient.getTasksByFilter(filterArgs); const matchingTasksData = tasksResponse.results || []; if (matchingTasksData.length === 0) { return { content: [{ type: "text", text: `No tasks found matching the filter query "${args.query}"` }], isError: false, }; } // Asynchronously format tasks and fetch project names if necessary const formattedTaskList = await Promise.all(matchingTasksData.map(async (task: any) => { let taskDisplay = formatTask(task); // formatTask now includes Project ID if (task.projectId) { try { const project = await todoistClient.getProject(task.projectId); taskDisplay += `\n Project Name: ${project.name}`; } catch (projectError: any) { // Silently ignore project fetch errors for search, or log them // taskDisplay += `\n Project Name: (Error fetching project details)`; console.error(`Error fetching project ${task.projectId} for search result: ${projectError.message}`); } } return taskDisplay; })); const taskListString = formattedTaskList.join('\n\n'); const nextCursorMessage = tasksResponse.nextCursor ? `\n\nNext cursor for more results: ${tasksResponse.nextCursor}` : ''; return { content: [{ type: "text", text: `Found ${matchingTasksData.length} task(s) matching "${args.query}":\n\n${taskListString}${nextCursorMessage}` }], isError: false, }; }
  • JSON schema definition for the todoist_search_tasks tool, specifying input parameters: required 'query' string, optional 'projectId' and 'limit'.
    const SEARCH_TASKS_TOOL: Tool = { name: "todoist_search_tasks", description: "Search for tasks by content/name (fallback for when ID is not known)", inputSchema: { type: "object", properties: { query: { type: "string", description: "Search query to find tasks by content" }, projectId: { type: "string", description: "Limit search to specific project (optional)" }, limit: { type: "number", description: "Maximum number of results (default: 10) (optional)", default: 10 } }, required: ["query"] } };
  • src/index.ts:1083-1121 (registration)
    Registration of the todoist_search_tasks tool (as SEARCH_TASKS_TOOL) in the list of available tools returned by the ListToolsRequestSchema handler.
    server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ // Task tools CREATE_TASK_TOOL, QUICK_ADD_TASK_TOOL, GET_TASKS_TOOL, GET_TASK_TOOL, UPDATE_TASK_TOOL, DELETE_TASK_TOOL, COMPLETE_TASK_TOOL, REOPEN_TASK_TOOL, SEARCH_TASKS_TOOL, MOVE_TASK_TOOL, BULK_MOVE_TASKS_TOOL, // Project tools GET_PROJECTS_TOOL, GET_PROJECT_TOOL, CREATE_PROJECT_TOOL, UPDATE_PROJECT_TOOL, DELETE_PROJECT_TOOL, // Section tools GET_SECTIONS_TOOL, CREATE_SECTION_TOOL, UPDATE_SECTION_TOOL, DELETE_SECTION_TOOL, // Label tools CREATE_LABEL_TOOL, GET_LABEL_TOOL, GET_LABELS_TOOL, UPDATE_LABEL_TOOL, DELETE_LABEL_TOOL, // Comment tools CREATE_COMMENT_TOOL, GET_COMMENT_TOOL, GET_COMMENTS_TOOL, UPDATE_COMMENT_TOOL, DELETE_COMMENT_TOOL, ], }));
  • Type guard helper function used to validate the input arguments for the todoist_search_tasks handler.
    function isSearchTasksArgs(args: unknown): args is { query: string; projectId?: string; limit?: number; } { return ( typeof args === "object" && args !== null && "query" in args && typeof (args as { query: string }).query === "string" ); }

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/kydycode/todoist-mcp-server-ext'

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