donetick-mcp-server

jason1365/donetick-mcp-server

3.2

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.

Tools
6
Resources
0
Prompts
0

Donetick MCP Server

PyPI version Python 3.11+ License: MIT GitHub

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 --refresh flag
  • ✅ 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: uv installed (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

  1. Clone the repository:

    git clone https://github.com/jason1365/donetick-mcp-server.git
    cd donetick-mcp-server
    
  2. Create .env file:

    cp .env.example .env
    # Edit .env with your configuration
    
  3. Configure environment variables:

    DONETICK_BASE_URL=https://your-instance.com
    DONETICK_USERNAME=your_username
    DONETICK_PASSWORD=your_password
    LOG_LEVEL=INFO
    
  4. 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:

  1. Server logs in with your credentials on startup
  2. JWT token received and stored in memory
  3. Token automatically refreshed before expiration
  4. No manual token management required

Security:

  • Credentials stored only in environment variables or .env file
  • 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 status
  • assigned_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 format
  • created_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 ID
  • assignees (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 ID
  • completed_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

VariableRequiredDefaultDescription
DONETICK_BASE_URLYes-Your Donetick instance URL (must use HTTPS)
DONETICK_USERNAMEYes-Your Donetick username
DONETICK_PASSWORDYes-Your Donetick password
LOG_LEVELNoINFOLogging level (DEBUG, INFO, WARNING, ERROR)
RATE_LIMIT_PER_SECONDNo10.0Requests per second limit
RATE_LIMIT_BURSTNo10Maximum 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

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

  1. Full API Used: Not the external API (eAPI) - uses internal Full API
  2. Field Casing: Consistent camelCase throughout (name, description, dueDate, createdBy)
  3. Trailing Slashes: List endpoints include trailing slashes for proper routing
  4. Authentication: JWT Bearer tokens with automatic management
  5. Complete Feature Support: All 26+ chore creation fields available
  6. Automatic Token Refresh: JWT tokens refreshed transparently
  7. Circle Scoped: All operations scoped to your circle (household/team)
  8. No Premium Restrictions: All features available through full API

Troubleshooting

Common Issues

"DONETICK_BASE_URL environment variable is required"

  • Make sure your .env file 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_SECOND if 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 .env file)
  • 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:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass
  5. Submit a pull request

License

MIT License - see LICENSE file for details

Acknowledgments

Support


Built with ❤️ for the Donetick and MCP communities