jason1365/donetick-mcp-server
If you are the rightful owner of donetick-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
Donetick MCP Server is a production-ready Model Context Protocol server for managing chores with Donetick, enabling interaction through a secure API.
Donetick MCP Server
A Model Context Protocol (MCP) server for Donetick chores management. Enables Claude and other MCP-compatible AI assistants to interact with your Donetick instance through a rate-limited API.
Features
- 16 MCP Tools: Complete chore management (list, get, create, complete, update, delete, skip), label organization (list, create, update, delete), circle member information, user management (list circle users, get user profile)
- Full API Integration: Uses Donetick Full API (/api/v1/) with all endpoints properly configured with trailing slashes
- Complete Field Support: All 26+ chore creation fields working including frequency metadata, rolling schedules, multiple assignees, assignment strategies, notifications, labels, priority, points, sub-tasks, and more
- Consistent Field Casing: camelCase fields throughout (name, description, dueDate, createdBy, etc.)
- Specialized Update Tools: Update chore details, priority, and assignee with dedicated endpoints
- JWT Authentication: Automatic token management with transparent refresh
- Smart Caching: Intelligent caching for get_chore operations (60s TTL by default)
- Rate Limiting: Token bucket algorithm prevents API overload
- Retry Logic: Exponential backoff with jitter for resilient operations
- Async/Await: Non-blocking operations using httpx
- Input Validation: Pydantic field validators with sanitization
- Security Hardened: HTTPS enforcement, sanitized logging, secure error messages, JWT token security
- Docker Support: Containerized deployment with security best practices
- Comprehensive Testing: Mocked unit/integration tests + live API test framework with pytest
- Type Safety: Pydantic models for request/response validation
Quick Start
Easiest installation (Claude Code CLI):
claude mcp add donetick uvx donetick-mcp-server@latest
Then configure your Donetick credentials when prompted.
Or install manually with uvx:
# Install uv (one-time setup)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Add to Claude Desktop config
# ~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"donetick": {
"command": "uvx",
"args": ["--refresh", "donetick-mcp-server"],
"env": {
"DONETICK_BASE_URL": "https://your-instance.com",
"DONETICK_USERNAME": "your_username",
"DONETICK_PASSWORD": "your_password"
}
}
}
}
Benefits:
- ✅ No installation required - runs directly from PyPI
- ✅ Auto-updates with
--refreshflag - ✅ Isolated environment - no conflicts
- ✅ Works on Windows, macOS, Linux
Requirements
- Donetick instance (self-hosted or cloud)
- Donetick account credentials (username and password)
- For uvx method:
uvinstalled (see Quick Start) - For other methods: Python 3.11 or higher
Installation
Option 1: uvx (Recommended - No Installation Required)
See Quick Start above.
The --refresh flag ensures you always get the latest version when Claude Desktop restarts.
Option 2: Docker
-
Clone the repository:
git clone https://github.com/jason1365/donetick-mcp-server.git cd donetick-mcp-server -
Create
.envfile:cp .env.example .env # Edit .env with your configuration -
Configure environment variables:
DONETICK_BASE_URL=https://your-instance.com DONETICK_USERNAME=your_username DONETICK_PASSWORD=your_password LOG_LEVEL=INFO -
Build and run:
docker-compose build docker-compose up -d
Option 3: pip install (For System Integration)
If you want to install globally or in a virtual environment:
# Install from PyPI
pip install donetick-mcp-server
# Or install for development
git clone https://github.com/jason1365/donetick-mcp-server.git
cd donetick-mcp-server
pip install -e .
# Run the server
donetick-mcp-server
# Or: python -m donetick_mcp.server
Then configure Claude Desktop to use the installed command:
{
"mcpServers": {
"donetick": {
"command": "donetick-mcp-server",
"env": {
"DONETICK_BASE_URL": "https://your-instance.com",
"DONETICK_USERNAME": "your_username",
"DONETICK_PASSWORD": "your_password"
}
}
}
}
Authentication
The MCP server uses JWT-based authentication with your Donetick credentials.
What You Need:
- Your Donetick username (same as web login)
- Your Donetick password (same as web login)
How It Works:
- Server logs in with your credentials on startup
- JWT token received and stored in memory
- Token automatically refreshed before expiration
- No manual token management required
Security:
- Credentials stored only in environment variables or
.envfile - JWT tokens kept in memory only (never persisted to disk)
- Automatic token refresh prevents session expiration
- HTTPS required for all connections
Claude Desktop Integration
Easiest Method - Claude Code CLI:
claude mcp add donetick uvx donetick-mcp-server@latest
Or manually edit the configuration file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Linux: ~/.config/Claude/claude_desktop_config.json
uvx Configuration (Recommended)
{
"mcpServers": {
"donetick": {
"command": "uvx",
"args": ["--refresh", "donetick-mcp-server"],
"env": {
"DONETICK_BASE_URL": "https://your-instance.com",
"DONETICK_USERNAME": "your_username",
"DONETICK_PASSWORD": "your_password"
}
}
}
}
Note: The --refresh flag automatically updates to the latest version.
Docker Configuration
{
"mcpServers": {
"donetick": {
"command": "docker",
"args": [
"exec",
"-i",
"donetick-mcp-server",
"python",
"-m",
"donetick_mcp.server"
]
}
}
}
pip install Configuration
{
"mcpServers": {
"donetick": {
"command": "donetick-mcp-server",
"env": {
"DONETICK_BASE_URL": "https://your-instance.com",
"DONETICK_USERNAME": "your_username",
"DONETICK_PASSWORD": "your_password"
}
}
}
}
After updating the configuration, restart Claude Desktop.
Available Tools
1. list_chores
List all chores with optional filtering.
Parameters:
filter_active(boolean, optional): Filter by active statusassigned_to_user_id(integer, optional): Filter by assigned user ID
Example:
List all active chores assigned to me
2. get_chore
Get details of a specific chore by ID.
Parameters:
chore_id(integer, required): The chore ID
Example:
Show me details of chore 123
3. create_chore
Create a new chore with full configuration support.
Basic Parameters:
name(string, required): Chore name (1-200 characters)description(string, optional): Chore description (max 5000 characters)due_date(string, optional): Due date in YYYY-MM-DD or RFC3339 formatcreated_by(integer, optional): Creator user ID
Recurrence/Frequency Parameters:
frequency_type(string, optional): How often chore repeats - "once", "daily", "weekly", "monthly", "yearly", "interval_based" (default: "once")frequency(integer, optional): Frequency multiplier, e.g., 1=weekly, 2=biweekly (default: 1)frequency_metadata(object, optional): Additional frequency config like{"days": [1,3,5], "time": "09:00"}is_rolling(boolean, optional): Rolling schedule (next due based on completion) vs fixed (default: false)
User Assignment Parameters:
assigned_to(integer, optional): Primary assigned user IDassignees(array, optional): Multiple assignees as[{"userId": 1}, {"userId": 2}]assign_strategy(string, optional): Assignment strategy - "least_completed", "round_robin", "random" (default: "least_completed")
Notification Parameters:
notification(boolean, optional): Enable notifications (default: false)nagging(boolean, optional): Enable nagging/reminder notifications (default: false)predue(boolean, optional): Enable pre-due date notifications (default: false)
Organization Parameters:
priority(integer, optional): Priority level 1-5 (1=lowest, 5=highest)labels(array, optional): Label tags like["cleaning", "outdoor"]
Status Parameters:
is_active(boolean, optional): Active status - inactive chores are hidden (default: true)is_private(boolean, optional): Private chore visible only to creator (default: false)
Gamification Parameters:
points(integer, optional): Points awarded for completion
Advanced Parameters:
sub_tasks(array, optional): Sub-tasks/checklist items
Examples:
Create a simple one-time chore:
Create a chore called "Take out trash" due on 2025-11-10
Create a recurring chore with notifications:
Create a weekly chore "Clean kitchen" every Monday at 9am with priority 4,
enable nagging notifications, and assign it to user 1
Create an advanced chore:
Create a chore "Grocery shopping" that repeats weekly on Mondays and Wednesdays,
assign to users 1 and 2 using round robin strategy, with priority 3,
labels "shopping" and "outdoor", and award 10 points
4. complete_chore
Mark a chore as complete.
Parameters:
chore_id(integer, required): The chore IDcompleted_by(integer, optional): User ID who completed it
Example:
Mark chore 123 as complete
5. delete_chore
Delete a chore permanently. Only the creator can delete.
Parameters:
chore_id(integer, required): The chore ID
Example:
Delete chore 123
6. get_circle_members
Get all members in your circle (household/team). Shows who you can assign chores to.
Parameters: None
Returns:
- User ID
- Username
- Display name
- Role (admin/member)
- Active status
- Points and redeemed points
Example:
Show me who's in my household
Who can I assign chores to?
List all circle members
Configuration
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
DONETICK_BASE_URL | Yes | - | Your Donetick instance URL (must use HTTPS) |
DONETICK_USERNAME | Yes | - | Your Donetick username |
DONETICK_PASSWORD | Yes | - | Your Donetick password |
LOG_LEVEL | No | INFO | Logging level (DEBUG, INFO, WARNING, ERROR) |
RATE_LIMIT_PER_SECOND | No | 10.0 | Requests per second limit |
RATE_LIMIT_BURST | No | 10 | Maximum burst size |
Rate Limiting
The server implements a token bucket rate limiter to prevent API overload:
- Default: 10 requests per second with burst capacity of 10
- Conservative: Starts conservative and can be increased based on your Donetick instance
- Respects 429: Automatically backs off when rate limited by the API
Retry Logic
- Exponential backoff with jitter for transient failures
- Maximum 3 retries for most operations
- Smart retry: Only retries on 5xx errors and 429 (rate limit)
- No retry on 4xx: Client errors fail immediately (except 429)
Development
Running Tests
Mocked Tests (fast, no Donetick instance required):
# Install dev dependencies
pip install -e ".[dev]"
# Run all tests (unit + integration with mocks)
pytest
# Run with coverage
pytest --cov=donetick_mcp --cov-report=html
# Run specific test file
pytest tests/test_client.py
pytest tests/test_server.py
# Run with verbose output
pytest -v
Live API Tests (requires Donetick instance):
# Create .env file with credentials (see Configuration section)
# Then run live API integration tests
pytest tests/integration/test_live_api.py -v
# Skip live tests
pytest -m "not live_api"
# Run only live tests
pytest -m live_api
Test Coverage Details:
- Mocked tests validate logic, retry behavior, rate limiting, error handling
- Live API tests verify endpoint routing, field casing compatibility, response formats
- Full coverage ensures both API client reliability and MCP tool correctness
Project Structure
donetick-mcp-server/
├── src/donetick_mcp/
│ ├── __init__.py
│ ├── server.py # MCP server implementation
│ ├── client.py # Donetick API client
│ ├── models.py # Pydantic data models
│ └── config.py # Configuration management
├── tests/
│ ├── test_client.py # API client tests
│ └── test_server.py # MCP server tests
├── tmp/ # Temporary files (gitignored)
├── Dockerfile
├── docker-compose.yml
├── pyproject.toml
└── README.md
Note: The tmp/ directory is used for temporary test scripts and analysis files during development. It's gitignored and not included in releases.
API Documentation
This server uses the Donetick Full API (/api/v1/) with JWT authentication.
Official Resources
- Donetick Docs: https://docs.donetick.com/
- Donetick GitHub: https://github.com/donetick/donetick
API Architecture
Endpoints Used:
- List Chores:
GET /api/v1/chores/(requires trailing slash) - Get Chore:
GET /api/v1/chores/{id}(includes sub-tasks) - Create Chore:
POST /api/v1/chores/ - Update Chore:
PUT /api/v1/chores/{id}(name, description, nextDueDate) - Update Priority:
PUT /api/v1/chores/{id}/priority - Update Assignee:
PUT /api/v1/chores/{id}/assignee - Skip Chore:
PUT /api/v1/chores/{id}/skip - Complete Chore:
POST /api/v1/chores/{id}/do - Delete Chore:
DELETE /api/v1/chores/{id} - Get Members:
GET /api/v1/circles/members/(requires trailing slash)
Important: List endpoints require trailing slashes (/api/v1/chores/, /api/v1/circles/members/). This is handled automatically by the client.
Important Notes
- Full API Used: Not the external API (eAPI) - uses internal Full API
- Field Casing: Consistent camelCase throughout (name, description, dueDate, createdBy)
- Trailing Slashes: List endpoints include trailing slashes for proper routing
- Authentication: JWT Bearer tokens with automatic management
- Complete Feature Support: All 26+ chore creation fields available
- Automatic Token Refresh: JWT tokens refreshed transparently
- Circle Scoped: All operations scoped to your circle (household/team)
- No Premium Restrictions: All features available through full API
Troubleshooting
Common Issues
"DONETICK_BASE_URL environment variable is required"
- Make sure your
.envfile exists and is properly formatted - For Docker: ensure environment variables are passed in docker-compose.yml
"Rate limited, waiting..."
- The server is respecting API rate limits
- Consider reducing
RATE_LIMIT_PER_SECONDif this happens frequently
"Connection refused" or timeout errors
- Verify your Donetick instance URL is correct
- Check that your Donetick instance is accessible
- Ensure firewall rules allow outbound connections
"401 Unauthorized" or "Invalid credentials"
- Verify your username and password are correct
- Check that your account is not locked or disabled
- Ensure you can login to Donetick web interface with the same credentials
- Check for typos in environment variables
Tools not showing in Claude
- Restart Claude Desktop after configuration changes
- Check Claude Desktop logs for errors
- Verify the configuration file path is correct
Debugging
Enable debug logging:
export LOG_LEVEL=DEBUG
Or in Docker:
environment:
- LOG_LEVEL=DEBUG
View Docker logs:
docker-compose logs -f donetick-mcp
Security
- Credentials: Never commit credentials to version control (use
.envfile) - JWT Tokens: Stored in memory only, never persisted to disk
- Automatic Token Refresh: Prevents session expiration without user intervention
- Docker Isolation: Runs as non-root user in container
- Resource Limits: Memory and CPU limits prevent resource exhaustion
- Input Validation: Pydantic models validate all inputs
- HTTPS Required: Server enforces HTTPS for all Donetick connections
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
License
MIT License - see LICENSE file for details
Acknowledgments
- Donetick - Open source chores management
- Model Context Protocol - MCP specification
- Anthropic - MCP SDK and Claude
Support
- Issues: https://github.com/jason1365/donetick-mcp-server/issues
- Donetick Docs: https://docs.donetick.com
- MCP Docs: https://modelcontextprotocol.io
Built with ❤️ for the Donetick and MCP communities