import { TodoistApi } from '@doist/todoist-api-typescript'
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { addMetaToTool, registerResource, registerTool } from './mcp-helpers.js'
import { addComments } from './tools/add-comments.js'
import { addProjects } from './tools/add-projects.js'
import { addSections } from './tools/add-sections.js'
import { addTasks } from './tools/add-tasks.js'
import { completeTasks } from './tools/complete-tasks.js'
import { deleteObject } from './tools/delete-object.js'
import { fetch } from './tools/fetch.js'
import { fetchObject } from './tools/fetch-object.js'
import { findActivity } from './tools/find-activity.js'
import { findComments } from './tools/find-comments.js'
import { findCompletedTasks } from './tools/find-completed-tasks.js'
import { findProjectCollaborators } from './tools/find-project-collaborators.js'
import { findProjects } from './tools/find-projects.js'
import { findSections } from './tools/find-sections.js'
import { findTasks } from './tools/find-tasks.js'
import { findTasksByDate } from './tools/find-tasks-by-date.js'
import { createFindTasksByDateResource } from './tools/find-tasks-by-date.resource.js'
import { getOverview } from './tools/get-overview.js'
import { manageAssignments } from './tools/manage-assignments.js'
import { search } from './tools/search.js'
import { updateComments } from './tools/update-comments.js'
import { updateProjects } from './tools/update-projects.js'
import { updateSections } from './tools/update-sections.js'
import { updateTasks } from './tools/update-tasks.js'
import { userInfo } from './tools/user-info.js'
import { loadTaskListWidget } from './utils/widget-loader.js'
const taskListWidget = loadTaskListWidget()
const TASK_CARD_FILE_NAME = taskListWidget.fileName
const taskCardHtml = taskListWidget.content
const instructions = `
## Todoist Task and Project Management Tools
You have access to comprehensive Todoist management tools for personal productivity and team collaboration. Use these tools to help users manage tasks, projects, sections, comments, and assignments effectively.
### Core Capabilities:
- Create, update, complete, and search tasks with rich metadata (priorities, due dates, durations, assignments)
- Manage projects and sections with flexible organization
- Handle comments and collaboration features
- Bulk assignment operations for team workflows
- Get overviews and insights about workload and progress
### Tool Usage Guidelines:
**Task Management:**
- **add-tasks**: Create tasks with content, description, priority (p1=highest, p2=high, p3=medium, p4=lowest/default), dueString (natural language like "tomorrow", "next Friday", "2024-12-25"), deadlineDate (ISO 8601 format like "2025-12-31" for immovable constraints), duration (formats like "2h", "90m", "2h30m"), and assignments to project collaborators
- **update-tasks**: Modify existing tasks - get task IDs from search results first, only include fields that need changes. Supports deadlineDate (ISO 8601 format like "2025-12-31") updates and removals (use "remove" to clear)
- **complete-tasks**: Mark tasks as done using task IDs
- **find-tasks**: Search by text, project/section/parent container, responsible user, or labels. Requires at least one search parameter
- **find-tasks-by-date**: Get tasks by date range (startDate: YYYY-MM-DD or 'today' which includes overdue tasks) or specific day counts
- **find-completed-tasks**: View completed tasks by completion date or original due date (returns all collaborators unless filtered)
**Project & Organization:**
- **add-projects/update-projects/find-projects**: Manage project lifecycle with names, favorites, and view styles (list/board/calendar)
- **add-sections/update-sections/find-sections**: Organize tasks within projects using sections
- **get-overview**: Get comprehensive Markdown overview of entire account or specific project with task hierarchies
**Collaboration & Comments:**
- **add-comments/update-comments/find-comments**: Manage task and project discussions
- **find-project-collaborators**: Find team members by name or email for assignments
- **manage-assignments**: Bulk assign/unassign/reassign up to 50 tasks with atomic operations and dry-run validation
**Activity & Audit:**
- **find-activity**: Retrieve recent activity logs to monitor and audit changes. Shows events from all users by default; use initiatorId to filter by specific user. Filter by object type (task/project/comment), event type (added/updated/deleted/completed/uncompleted/archived/unarchived/shared/left), and specific objects (objectId, projectId, taskId). Useful for tracking who did what and when. Note: Date-based filtering is not supported.
**General Operations:**
- **delete-object**: Remove projects, sections, tasks, or comments by type and ID
- **fetch-object**: Fetch a single task, project, comment, or section by its ID
- **user-info**: Get user details including timezone, goals, and plan information
### Best Practices:
1. **Task Creation**: Write clear, actionable task titles. Use natural language for due dates ("tomorrow", "next Monday"). Set appropriate priorities and include detailed descriptions when needed.
2. **Search Strategy**: Use specific search queries combining multiple filters for precise results. When searching for tasks, start with broader queries and narrow down as needed.
3. **Assignments**: Always validate project collaborators exist before assigning tasks. Use find-project-collaborators to verify user access.
4. **Bulk Operations**: When working with multiple items, prefer bulk tools (complete-tasks, manage-assignments) over individual operations for better performance.
5. **Date Handling**: All dates respect user timezone settings. Use 'today' keyword for dynamic date filtering (includes overdue tasks).
6. **Labels**: Use label filtering with AND/OR operators for advanced task organization. Most search tools support labels parameter.
7. **Pagination**: Large result sets use cursor-based pagination. Use limit parameter to control result size (default varies by tool).
8. **Error Handling**: All tools provide detailed error messages and next-step suggestions. Pay attention to validation feedback for corrective actions.
### Common Workflows:
- **Daily Planning**: Use find-tasks-by-date with 'today' and get-overview for project status
- **Team Assignment**: find-project-collaborators → add-tasks with responsibleUser → manage-assignments for bulk changes
- **Task Search**: find-tasks with multiple filters → update-tasks or complete-tasks based on results
- **Project Organization**: add-projects → add-sections → add-tasks with projectId and sectionId
- **Progress Reviews**: find-completed-tasks with date ranges → get-overview for project summaries
- **Activity Auditing**: find-activity with event/object filters to track changes, monitor team activity, or investigate specific actions
Always provide clear, actionable task titles and descriptions. Use the overview tools to give users context about their workload and project status.
`
/**
* Create the MCP server.
* @param todoistApiKey - The API key for the todoist account.
* @param baseUrl - The base URL for the todoist API.
* @returns the MCP server.
*/
function getMcpServer({ todoistApiKey, baseUrl }: { todoistApiKey: string; baseUrl?: string }) {
const server = new McpServer(
{ name: 'todoist-mcp-server', version: '0.1.0' },
{
capabilities: {
tools: { listChanged: true },
},
instructions,
},
)
const todoist = new TodoistApi(todoistApiKey, { baseUrl })
/**
* ChatGPT Apps
*/
// Find Tasks by Date
// ChatGPT Apps are caching aggressively with no controls, we're injecting a
// build timestamp into the URI to bust the cache reliably. Ideally, in the
// future they offer best cache-controls.
// ref: https://www.epicai.pro/chat-gpt-app-code-walkthrough-kbh1e#rough-edges-for-now
const findTasksByDateUri = `ui://widget/${TASK_CARD_FILE_NAME}`
const enhancedFindTasksByDateTool = addMetaToTool(findTasksByDate, {
'openai/outputTemplate': findTasksByDateUri,
'openai/toolInvocation/invoking': 'Displaying the task list',
'openai/toolInvocation/invoked': 'Displayed the task list',
})
const findTasksByDateResource = createFindTasksByDateResource(findTasksByDateUri, taskCardHtml)
registerResource(server, findTasksByDateResource)
/**
* Tools
*/
// Task management tools
registerTool(addTasks, server, todoist)
registerTool(completeTasks, server, todoist)
registerTool(updateTasks, server, todoist)
registerTool(findTasks, server, todoist)
registerTool(enhancedFindTasksByDateTool, server, todoist)
registerTool(findCompletedTasks, server, todoist)
// Project management tools
registerTool(addProjects, server, todoist)
registerTool(updateProjects, server, todoist)
registerTool(findProjects, server, todoist)
// Section management tools
registerTool(addSections, server, todoist)
registerTool(updateSections, server, todoist)
registerTool(findSections, server, todoist)
// Comment management tools
registerTool(addComments, server, todoist)
registerTool(findComments, server, todoist)
registerTool(updateComments, server, todoist)
// Activity and audit tools
registerTool(findActivity, server, todoist)
// General tools
registerTool(getOverview, server, todoist)
registerTool(deleteObject, server, todoist)
registerTool(fetchObject, server, todoist)
registerTool(userInfo, server, todoist)
// Assignment and collaboration tools
registerTool(findProjectCollaborators, server, todoist)
registerTool(manageAssignments, server, todoist)
// OpenAI MCP tools
registerTool(search, server, todoist)
registerTool(fetch, server, todoist)
return server
}
export { getMcpServer }