MCP server for Donetick chores management with JWT authentication, Full API support, and 20 MCP tools
Project description
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file donetick_mcp_server-0.3.7.tar.gz.
File metadata
- Download URL: donetick_mcp_server-0.3.7.tar.gz
- Upload date:
- Size: 66.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca8db8325392666c1ac22c08fe7201d1ce4f17cb022249eb7673076f016b326c
|
|
| MD5 |
5dfd29a2881a9e73247538b54cc5afd1
|
|
| BLAKE2b-256 |
39d74ad6abd85453c74ed055244adf1b816145e0cf45b4b1af9ee555bd16bc16
|
File details
Details for the file donetick_mcp_server-0.3.7-py3-none-any.whl.
File metadata
- Download URL: donetick_mcp_server-0.3.7-py3-none-any.whl
- Upload date:
- Size: 38.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2408e4eccb70f07b1061993184587451b2136b26f6c5692388d9d13c67b77123
|
|
| MD5 |
629bcbc15937b5f97add98d7b2c8c8f4
|
|
| BLAKE2b-256 |
6f904aba6c9f572fcc422032bc5d3b2a5bb9cb65a9b565f08fb55b527626d2f4
|