Skip to main content
Glama
Todolist MCP Server
by jgn35

Todolist MCP Server

Python License: MIT Code Style: Ruff

A Model Context Protocol (MCP) server for task management. Built with Python 3.12+, FastMCP, SQLAlchemy, and SQLite.

Features

  • Task Management: Create, read, update, delete, and complete tasks

  • Filtering: List tasks by status, priority, or due date

  • Authentication: Secure token-based authentication

  • Persistence: SQLite database for data storage

  • MCP Protocol: Full MCP server implementation with 6 tools

Available MCP Tools

Tool

Description

create_task

Create a new task with title, description, due date, and priority

get_task

Retrieve a task by its ID

list_tasks

List all tasks with optional filters (status, priority, due date)

update_task

Update task attributes (title, description, due date, priority, status)

delete_task

Delete a task by its ID

complete_task

Mark a task as completed

Related MCP server: tasqr-mcp

Quick Start

Prerequisites

  • Python 3.12 or higher

  • uv (recommended) or pip

Installation

# Clone the repository
git clone https://github.com/jgn35/Todolist-mcp.git
cd Todolist-mcp

# Install dependencies with uv
uv sync

# Or with pip
pip install -e .

Generate Authentication Token

All MCP tools require a valid authentication token. Generate one first:

# Using uv
uv run todolist-mcp-generate-token

# Or with Python
python -m todolist_mcp.cli generate-token

# Or directly
python -c "from todolist_mcp.infrastructure.auth_adapter.token_manager import TokenManager; print(TokenManager().generate_token())"

Important: Save the generated token. You'll need it for all MCP tool calls.

Run the Server

# Using uv
uv run todolist-mcp

# Or with Python
python -m todolist_mcp

# Or directly
python -c "from todolist_mcp import main; main()"

The server will start and listen on stdin/stdout for MCP requests.

Usage Examples

Using MCP Client

import asyncio
from mcp import Client

async def main():
    client = Client(command="uv run todolist-mcp")
    await client.connect()
    
    token = "YOUR_GENERATED_TOKEN"
    
    # Create a task
    task = await client.call_tool("create_task", {
        "title": "Learn MCP",
        "description": "Understand Model Context Protocol",
        "priority": "high",
        "token": token
    })
    print(f"Created task: {task['id']}")
    
    # List tasks
    result = await client.call_tool("list_tasks", {"token": token})
    print(f"Total tasks: {result['total']}")
    
    await client.disconnect()

asyncio.run(main())

Direct Tool Calls

from todolist_mcp import mcp
import asyncio

async def example():
    token = "YOUR_GENERATED_TOKEN"
    
    # Create task
    task = await mcp.create_task(
        title="Test Task",
        description="A test task",
        priority="high",
        token=token
    )
    print(f"Created: {task}")
    
    # List tasks
    result = await mcp.list_tasks(token=token)
    print(f"Tasks: {result['tasks']}")

asyncio.run(example())

Project Structure

todolist-mcp/
├── src/
│   └── todolist_mcp/
│       ├── __init__.py           # MCP server entry point & tool definitions
│       ├── cli.py                # Command-line interface for token management
│       ├── domain/
│       │   ├── __init__.py
│       │   └── entities.py        # Task, Priority, TaskStatus entities
│       ├── application/
│       │   ├── __init__.py
│       │   ├── use_cases/         # Clean Architecture use cases
│       │   │   ├── __init__.py
│       │   │   ├── create_task.py
│       │   │   ├── get_task.py
│       │   │   ├── list_tasks.py
│       │   │   ├── update_task.py
│       │   │   ├── delete_task.py
│       │   │   └── complete_task.py
│       │   └── services/
│       │       └── auth_service.py
│       └── infrastructure/
│           ├── __init__.py
│           ├── sqlite_adapter/    # SQLite persistence
│           │   ├── __init__.py
│           │   ├── models.py      # SQLAlchemy models
│           │   └── repository.py  # TaskRepository implementation
│           └── auth_adapter/     # Authentication
│               ├── __init__.py
│               ├── models.py
│               └── token_manager.py
├── tests/
│   ├── __init__.py
│   ├── unit/
│   │   ├── __init__.py
│   │   ├── domain/
│   │   │   └── test_entities.py
│   │   └── application/
│   │       ├── __init__.py
│   │       ├── test_create_task.py
│   │       ├── test_get_task.py
│   │       ├── test_list_tasks.py
│   │       ├── test_update_task.py
│   │       ├── test_delete_task.py
│   │       ├── test_complete_task.py
│   │       └── test_create_task_missing_title.py
│   └── integration/
│       ├── __init__.py
│       ├── test_mcp_tools_integration.py
│       └── mcp_tools/
│           └── __init__.py
├── pyproject.toml                 # Project configuration
├── AGENTS.md                      # Project context for agents
└── LICENSE                        # MIT License

Configuration

Environment Variables

Variable

Description

Default

TODOLIST_MCP_DB_PATH

Path to SQLite database

~/.todolist-mcp/todolist.db

TODOLIST_MCP_TOKEN_PATH

Path to token file

~/.todolist-mcp/token.txt

Token Storage

Tokens are stored in ~/.todolist-mcp/token.txt by default. The directory is created automatically on first run.

Development

Setup Development Environment

# Install development dependencies
uv sync --all-extras

# Or with pip
pip install -e ".[dev]"

Running Tests

# Run all tests
uv run pytest

# Run with verbose output
uv run pytest -v

# Run specific test file
uv run pytest tests/unit/application/test_create_task.py

# Run integration tests
uv run pytest tests/integration/

# Run with coverage
uv run pytest --cov=src/todolist_mcp --cov-report=term-missing

Linting & Type Checking

# Run linter (Ruff)
uv run ruff check .

# Auto-fix linting issues
uv run ruff check . --fix

# Run type checker (Pyright)
uv run pyright

Code Formatting

This project uses Ruff for linting. Configure your editor to use:

  • Line length: 100 characters

  • Python version: 3.12

Architecture

Clean Architecture Layers

┌─────────────────────────────────────────┐
│              MCP Server                  │  ← FastMCP tools
├─────────────────────────────────────────┤
│           Application Layer               │  ← Use cases
├─────────────────────────────────────────┤
│             Domain Layer                  │  ← Entities & interfaces
├─────────────────────────────────────────┤
│          Infrastructure Layer             │  ← SQLite, Auth
└─────────────────────────────────────────┘

Data Flow

MCP Request → Auth Validation → Use Case → Repository → SQLite

Task Entity

from todolist_mcp.domain.entities import Task, Priority, TaskStatus

task = Task(
    title="My Task",
    description="Task description",
    due_date="2026-12-31 23:59:59",
    priority=Priority.HIGH,
    status=TaskStatus.PENDING
)

Priority Levels

  • low - Low priority

  • medium - Medium priority (default)

  • high - High priority

Status Values

  • pending - Task is pending (default)

  • completed - Task is completed

  • cancelled - Task is cancelled

Filtering Tasks

The list_tasks tool supports various filters:

Status Filter

# List only pending tasks
list_tasks(status="pending", token=token)

# List completed tasks
list_tasks(status="completed", token=token)

Priority Filter

# List high priority tasks
list_tasks(priority="high", token=token)

Due Date Filter

# List tasks due today
list_tasks(due_date="today", token=token)

# List tasks due tomorrow
list_tasks(due_date="tomorrow", token=token)

# List overdue tasks
list_tasks(due_date="overdue", token=token)

# List tasks in date range
list_tasks(due_date="2026-08-01..2026-08-31", token=token)

# List tasks due on specific date
list_tasks(due_date="2026-12-31", token=token)

Pagination

# Get first 10 tasks
list_tasks(limit=10, offset=0, token=token)

# Get next 10 tasks
list_tasks(limit=10, offset=10, token=token)

Error Handling

All tools raise ValueError with descriptive messages for:

  • Invalid or missing authentication token

  • Missing required fields (e.g., title for create_task)

  • Invalid field values (e.g., invalid priority)

  • Task not found

  • Attempting to modify a completed task

Contributing

  1. Fork the repository

  2. Create a feature branch (git checkout -b feature/your-feature)

  3. Make your changes

  4. Run tests and linting:

    uv run pytest
    uv run ruff check .
    uv run pyright
  5. Commit your changes (git commit -m 'Add some feature')

  6. Push to the branch (git push origin feature/your-feature)

  7. Open a Pull Request

Pull Request Guidelines

  • Follow existing code style

  • Add tests for new functionality

  • Update documentation as needed

  • Keep commits atomic and well-described

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

Available Tools

6 tools
complete_taskComplete TaskA

Mark a task as completed.

Inputs: task_id (required). Returns: object

create_taskCreate TaskB

Create a new task.

Inputs: title (required), due_date, priority, description. Returns: object

delete_taskDelete TaskC

Delete a task.

Inputs: task_id (required). Returns: object

get_taskGet TaskB

Get a task by ID.

Inputs: task_id (required). Returns: object

list_tasksList TasksC

List tasks with optional filters.

Inputs: limit, offset, status, due_date, +1 more. Returns: object

update_taskUpdate TaskC

Update a task.

Inputs: task_id (required), title, status, due_date, +2 more. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.3/5.0

    Scored across 6 tools

    Disambiguation5/5

    Each tool targets a distinct task operation: create, get, list, update, delete, and complete. No overlap or ambiguity between them.

    Naming Consistency5/5

    All tool names follow the consistent verb_noun pattern using snake_case: create_task, get_task, list_tasks, update_task, delete_task, complete_task.

    Tool Count5/5

    Six tools is a well-scoped set for a task management server, covering the essential lifecycle without unnecessary bloat.

    Completeness5/5

    The tool set covers full CRUD operations plus a completion action, providing complete lifecycle coverage for tasks. No obvious gaps.

    Maintenance

    ActivityStale
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI agents to manage task state through MCP, including creating, updating, and tracking tasks, with support for client-side encryption and secure local credential storage.
      17 npm
      MIT
    • F
      license
      Not graded
      quality
      C
      maintenance
      Enables task management through MCP, including creation, retrieval, update, deletion, and filtering tasks by completion status using a MySQL-backed server.
      -