Todoist MCP App with interactive UI for task management
npm install todoist-mcp-appAn interactive Todoist task management application built with the Model Context Protocol (MCP) Apps framework. This app provides a rich visual interface for managing your Todoist tasks directly within AI chat conversations.
!License
!Node
!TypeScript
!Tests
!Coverage
- Interactive Dashboard - Full task management interface with sidebar navigation
- Quick Add - Fast task creation with natural language support (e.g., "Buy milk tomorrow p1 #Shopping")
- Project & Label Filtering - Filter tasks by project, label, or time (Today, Upcoming, Inbox)
- Task CRUD - Complete, create, edit, and delete tasks with inline confirmation
- Optimistic Updates - Immediate UI feedback for all operations
- MCP Integration - Works seamlessly with Claude Desktop and other MCP hosts
- Comprehensive Testing - 111 tests (90 unit + 21 E2E) with 85%+ coverage
- Node.js >= 18.0.0
- npm >= 9.0.0
- Todoist API Token - Get yours from Todoist Developer Settings
1. Clone or download this repository
2. Install dependencies:
``bash`
npm install
`
3. Copy the environment file and add your Todoist API token:
bash`
cp .env.example .env
.env
Edit and add your token:`
`
TODOIST_API_TOKEN=your_api_token_here
Get your API token from: https://app.todoist.com/app/settings/integrations/developer
Build both the UI and server:
`bash`
npm run build
Or build separately:
`bash`
npm run build:ui # Build UI bundles
npm run build:server # Build server TypeScript
Start the server:
`bash`
npm start
The server will start at http://localhost:3001/mcp
Run in development mode with hot reload:
`bash`
npm run dev
Add to your claude_desktop_config.json:
Windows: %APPDATA%\Claude\claude_desktop_config.json~/Library/Application Support/Claude/claude_desktop_config.json
macOS:
#### Option 1: Using npx (easiest)
`json`
{
"mcpServers": {
"todoist": {
"command": "npx",
"args": ["todoist-mcp-app"],
"env": {
"TODOIST_API_TOKEN": "your_api_token_here"
}
}
}
}
#### Option 2: Local installation
`json`
{
"mcpServers": {
"todoist": {
"command": "node",
"args": ["C:/path/to/todoist-mcp-app/dist/server/stdio.js"],
"env": {
"TODOIST_API_TOKEN": "your_api_token_here"
}
}
}
}
> Note: For local installation, replace C:/path/to/todoist-mcp-app with the actual path. Use forward slashes even on Windows.
After configuration, restart Claude Desktop. You can then ask Claude to:
- "Show me my Todoist dashboard"
- "Add a task to buy groceries tomorrow"
- "What tasks do I have for today?"
1. Start the server locally:
`bash`
npm start
2. In another terminal, expose via cloudflared:
`bash`
npx cloudflared tunnel --url http://localhost:3001
3. Add the generated URL as a custom connector in Claude:
- Click your profile → Settings → Connectors → Add custom connector
You can also run the dashboard directly in a browser:
`bash`
npm startThen open: http://localhost:3001/dashboard?standalone
1. todoist-dashboard: Opens an interactive task dashboard
- Filter by: Today, Upcoming, Inbox, All
- Complete, edit, and delete tasks
- Navigate between projects
2. todoist-quick-add: Opens a quick add form
- Natural language input support
- Project, priority, due date, and label selectors
- todoist-complete-task: Mark a task as completetodoist-create-task
- : Create a new tasktodoist-update-task
- : Update an existing tasktodoist-delete-task
- : Delete a tasktodoist-reopen-task
- : Reopen a completed tasktodoist-get-tasks
- : Fetch tasks with optional filtertodoist-get-projects
- : Get all projectstodoist-get-labels
- : Get all labels
``
todoist-mcp-app/
├── src/
│ ├── server/ # MCP server code
│ │ ├── api/
│ │ │ └── todoist-client.ts # Todoist API wrapper
│ │ ├── __tests__/ # Server unit tests
│ │ ├── index.ts # HTTP server entry point
│ │ ├── stdio.ts # Stdio server (for Claude Desktop)
│ │ ├── server.ts # MCP tool & resource registration
│ │ └── types.ts # TypeScript interfaces
│ ├── ui/
│ │ ├── shared/ # Shared components & hooks
│ │ │ ├── components/
│ │ │ │ ├── __tests__/ # Component tests
│ │ │ │ ├── TaskItem.tsx
│ │ │ │ ├── TaskList.tsx
│ │ │ │ └── TaskForm.tsx
│ │ │ ├── hooks/
│ │ │ │ └── useApp.ts # MCP App hook
│ │ │ ├── styles/
│ │ │ └── utils/
│ │ │ └── __tests__/ # Utility tests
│ │ ├── dashboard/ # Dashboard UI
│ │ │ └── __tests__/ # Dashboard tests
│ │ └── quick-add/ # Quick Add UI
│ ├── mocks/ # MSW mocks for testing
│ └── test/ # Test setup
├── e2e/ # Playwright E2E tests
├── dist/ # Build output
├── .env # Environment variables (create this)
├── package.json
├── tsconfig.json # Client TypeScript config
├── tsconfig.server.json # Server TypeScript config
├── vite.config.ts # Vite build configuration
├── vitest.config.ts # Vitest test configuration
└── playwright.config.ts # Playwright E2E configuration
MCP Apps combine two components:
1. Tools: Registered with _meta.ui.resourceUri pointing to a UI resource
2. UI Resources: Bundled HTML/React apps served by the MCP server
When a tool is called:
1. The host (Claude) fetches the UI resource
2. The UI renders in a sandboxed iframe
3. The UI receives tool results via app.ontoolresultapp.callServerTool()
4. User interactions call to communicate back
The project includes comprehensive testing with 111 tests:
`bashUnit tests (watch mode)
npm test
$3
| Category | Tests | Coverage |
|----------|-------|----------|
| Unit Tests | 90 | 85%+ |
| E2E Tests | 21 | Full user flows |
| Total | 111 | 85%+ |
$3
- Components: TaskItem, TaskList, TaskForm, Sidebar, Dashboard
- Hooks: useApp, useMockApp
- Utilities: Date formatting functions
- API Client: TodoistClient wrapper
- E2E Flows: Navigation, task operations, accessibility
Scripts Reference
| Script | Description |
|--------|-------------|
|
npm run dev | Start development server with hot-reload |
| npm run build | Build for production |
| npm run start | Start production HTTP server |
| npm run start:stdio | Start stdio server (for Claude Desktop) |
| npm test | Run unit tests in watch mode |
| npm run test:run | Run unit tests once |
| npm run test:coverage | Run tests with coverage report |
| npm run test:e2e | Run Playwright E2E tests |
| npm run test:e2e:ui | Run E2E tests with Playwright UI |Technologies
- Runtime: Node.js 18+
- Language: TypeScript 5.3
- UI Framework: React 18
- Build Tool: Vite 5 with single-file bundling
- MCP SDK: @modelcontextprotocol/sdk
- Todoist API: @doist/todoist-api-typescript
- Testing: Vitest, React Testing Library, Playwright, MSW
- Server: Express
Troubleshooting
$3
Make sure you have:
1. Created a
.env file with your token, OR
2. Set the TODOIST_API_TOKEN in your Claude Desktop config$3
Kill the existing process:
`bash
Windows
netstat -ano | findstr :3001
taskkill /F /PID macOS/Linux
lsof -i :3001
kill -9
`$3
1. Verify the path in
claude_desktop_config.json is correct
2. Make sure the project is built (npm run build)
3. Restart Claude Desktop completely
4. Check Claude Desktop logs for errors$3
When running standalone (not through Claude), add
?standalone to the URL:
`
http://localhost:3001/dashboard?standalone
`Contributing
1. Fork the repository
2. Create your feature branch (
git checkout -b feature/amazing-feature)
3. Run tests (npm run test:run && npm run test:e2e)
4. Commit your changes (git commit -m 'Add amazing feature')
5. Push to the branch (git push origin feature/amazing-feature`)MIT
- mcp-todoist by @greirson - This project is inspired by and built upon mcp-todoist, which provides an excellent MCP server for Todoist integration. Our project extends it with interactive UI components (Dashboard and Quick Add) using the MCP Apps framework.
- Todoist for their excellent API
- Anthropic for Claude and the MCP protocol
- Model Context Protocol for the MCP specification