mcp_todo

thijs-hakkenberg/mcp_todo

3.2

If you are the rightful owner of mcp_todo 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.

A Model Context Protocol (MCP) server that uses Git as the backend for a collaborative todo system.

Git-Based MCP Todo Server

A Model Context Protocol (MCP) server that uses Git as the backend for a collaborative todo system. Users interact via Claude Desktop or Claude Code, and changes sync through Git, leveraging Git's permission system and version control for team collaboration.

Features

  • Git-Backed Storage: All todos stored in a Git repository for version control
  • Collaborative: Multiple users can work on the same todo list via Git
  • Conflict Resolution: Automatic Last-Write-Wins (LWW) merge strategy for concurrent edits
  • Auto-Sync: Optional automatic synchronization with remote repository
  • Rich Todo Features: Priority levels, projects, tags, assignees, due dates, comments, and more
  • MCP Integration: Works seamlessly with Claude Desktop and Claude Code
  • Web-Based Kanban Board: Interactive Svelte 5 UI with drag-and-drop, filtering, and real-time updates
  • Telegram Bot: Manage todos via Telegram group chats with command-based interface

Architecture

MCP Integration (Claude Desktop/Claude Code)

Claude Desktop ←→ MCP Server (Node.js) ←→ Local Git Repo ←→ Remote Git (GitHub/GitLab)

Web-Based Kanban Board

Web Browser (Svelte) ←→ API Server (Express) ←→ MCP Server (Node.js) ←→ Local Git Repo ←→ Remote Git

Telegram Bot

Telegram User ←→ Telegram Bot API ←→ TodoBot (Node.js) ←→ MCP Server (stdio) ←→ Local Git Repo ←→ Remote Git

The system provides three interfaces:

  1. MCP Interface: Direct integration with Claude Desktop and Claude Code via stdio
  2. Web Interface: Browser-based kanban board via REST API
  3. Telegram Bot: Command-based todo management in Telegram group chats

Installation

Prerequisites

  • Node.js 20+
  • Git
  • Claude Desktop

Setup

  1. Clone this repository:
git clone https://github.com/yourusername/our_todo.git
cd our_todo
  1. Install dependencies:
npm install
  1. Build the project:
npm run build
  1. Create your todos repository:
mkdir ~/my-todos
cd ~/my-todos
git init
git commit --allow-empty -m "Initial commit"
# Optional: Add remote repository
git remote add origin https://github.com/yourusername/my-todos.git
git push -u origin main

Note: The system will automatically create the directory structure on first use. If you have an existing todos.json file, it will be automatically migrated to the new directory structure with a backup created.

  1. Configure Claude Desktop or Claude Code:

Configuration File

Add the following configuration to:

  • Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)
  • Claude Code: .claude/config.json in your project directory
{
  "mcpServers": {
    "git-todo": {
      "command": "node",
      "args": ["/absolute/path/to/our_todo/dist/index.js"],
      "env": {
        "TODO_REPO_PATH": "/Users/you/my-todos",
        "TODO_REPO_URL": "https://github.com/you/my-todos.git",
        "GIT_USER_NAME": "Your Name",
        "GIT_USER_EMAIL": "you@example.com",
        "AUTO_SYNC": "true",
        "SYNC_INTERVAL_SECONDS": "300"
      }
    }
  }
}

Note: Replace /absolute/path/to/our_todo with the actual path to this repository on your system, and update the environment variables with your specific configuration.

Alternative Setup for Claude Code

If you've already configured the MCP server in Claude Desktop, you can easily add it to Claude Code by running:

claude mcp add-from-claude-desktop

This will automatically copy the configuration from your Claude Desktop setup to Claude Code.

Running the Web-Based Kanban Board

The kanban board provides a visual interface for managing todos with drag-and-drop functionality, inline filtering, and real-time statistics.

Architecture

The kanban board consists of two components:

  1. API Server (Express): Bridges the web frontend and MCP server
  2. Web Frontend (Svelte 5): Interactive kanban board UI

Quick Start (Recommended)

  1. Configure your environment by creating a .env file:
cp .env.example .env
# Edit .env with your TODO_REPO_PATH and Git credentials
  1. Use the provided startup scripts for the easiest experience:
# Terminal 1: Start backend
./start-backend.sh

# Terminal 2: Start frontend
./start-frontend.sh

Then open http://localhost:31415 in your browser.

Note: The startup scripts will use default values if environment variables are not set, but it's recommended to configure .env with your actual repository path.

See for detailed instructions and troubleshooting.

Manual Setup and Running

  1. Install dependencies for both backend and frontend:
# Install backend dependencies (if not already done)
npm install

# Install frontend dependencies
cd web
npm install
cd ..
  1. Build the MCP server:
npm run build
  1. Configure environment variables:

Option A: Create a .env file (Recommended)

Create a .env file in the project root with your configuration:

cp .env.example .env
# Edit .env with your values

Example .env file:

# Path to your Git repository for storing todos
TODO_REPO_PATH=/Users/you/my-todos

# Optional: Remote Git repository URL for syncing
TODO_REPO_URL=https://github.com/you/my-todos.git

# Git user configuration
GIT_USER_NAME=Your Name
GIT_USER_EMAIL=you@example.com

# Optional: Auto-sync configuration
AUTO_SYNC=false
SYNC_INTERVAL_SECONDS=300

# API server configuration
PORT=3001
CORS_ORIGIN=http://localhost:5173
NODE_ENV=development

Option B: Export environment variables manually

export TODO_REPO_PATH="/Users/you/my-todos"
export TODO_REPO_URL="https://github.com/you/my-todos.git"
export GIT_USER_NAME="Your Name"
export GIT_USER_EMAIL="you@example.com"
  1. Start the API server:
# If using .env file, it will be loaded automatically
npm run start:api
  1. In a separate terminal, start the web frontend:
cd web
npm run dev
  1. Open your browser to http://localhost:31415

Environment Variables for API Server

The API server uses the same environment variables as Claude Desktop/Claude Code:

  • TODO_REPO_PATH: Path to local Git repository (default: ~/my-todos)
  • TODO_REPO_URL: Remote Git repository URL (optional)
  • GIT_USER_NAME: Git user name for commits
  • GIT_USER_EMAIL: Git user email for commits
  • PORT: API server port (default: 3001)
  • CORS_ORIGIN: CORS origin for web frontend (default: http://localhost:31415)
  • NODE_ENV: Environment mode (development/production)

Running with Docker

The Telegram bot can be deployed using Docker for improved reliability and easier management. Docker provides automatic restarts, isolated environments, and simplified deployment.

Quick Start:

# 1. Create environment file
cp .env.telegram.example .env.telegram

# 2. Edit with your configuration
nano .env.telegram

# 3. Build and start
docker build -f Dockerfile.telegram -t todo-telegram-bot:latest .
docker compose -f docker-compose.telegram.yml up -d

# 4. View logs
docker logs -f todo-telegram-bot

For detailed Docker deployment instructions, troubleshooting, and production setup, see .

Development Mode

For development with auto-reload:

# Terminal 1: Start API server in watch mode
npm run dev:api

# Terminal 2: Start web frontend in dev mode
cd web
npm run dev

Production Build

  1. Build both backend and frontend:
# Build backend
npm run build

# Build frontend
cd web
npm run build
cd ..
  1. Serve the production build:
# Start API server
npm run start:api

# In another terminal, preview the built frontend
cd web
npm run preview

Kanban Board Features

Kanban Board Screenshot

  • Four Columns: To Do, In Progress, Blocked, Done
  • Drag-and-Drop: Move todos between columns to change status
  • Inline Filters: Filter by search text, project, priority, tags, and assignee
  • Active Filters Display: See all active filters with individual clear buttons
  • Statistics: Real-time completion rates and status breakdown
  • Add Todos: Create new todos directly from the board with intelligent project autocomplete
  • Edit Todos: Double-click any card to view details and edit all fields
  • Project Autocomplete: Search existing projects or create new ones - prevents typos and duplicates
  • Priority Colors: Visual indicators for low, medium, high, and urgent priorities
  • Responsive Design: Works on desktop and mobile devices

Sharing the Same Todo Repository

The API server connects to the same Git repository as your Claude Desktop/Claude Code MCP server. This means:

  • Todos created in Claude Desktop appear in the kanban board
  • Todos created in the kanban board appear in Claude Desktop
  • Both interfaces share the same Git history and version control
  • Conflicts are automatically resolved using Last-Write-Wins strategy

Simply ensure both the MCP server (Claude Desktop config) and the API server use the same TODO_REPO_PATH.

Configuration

Environment Variables

  • TODO_REPO_PATH: Path to local Git repository (default: ~/my-todos)
  • TODO_REPO_URL: Remote Git repository URL (optional)
  • GIT_USER_NAME: Git user name for commits
  • GIT_USER_EMAIL: Git user email for commits
  • AUTO_SYNC: Enable automatic sync (true/false, default: false)
  • SYNC_INTERVAL_SECONDS: Sync interval in seconds (default: 300)

Usage

You can interact with your todos in two ways:

  1. Through Claude Desktop or Claude Code using natural language
  2. Through the Web-Based Kanban Board using a visual interface

MCP Commands (Claude Desktop/Claude Code)

Once configured, you can use natural language commands in Claude:

  • List todos: "Show me my todos"
  • Create todo: "Add a todo: Implement user authentication"
  • Batch create: "Create multiple todos: Setup project, Install dependencies, Configure linter"
  • Update todo: "Mark todo 123 as in-progress"
  • Complete todo: "Complete todo 456"
  • Delete todo: "Delete todo 789"
  • Search: "Search for todos about authentication"
  • Filter: "Show high priority todos in the backend project"
  • Add comment: "Add comment to todo 123: Started working on this"
  • Get stats: "Show todo statistics"
  • Manual sync: "Sync the repository"

Todo Properties

  • text: Todo description (required)
  • project: Project name (required)
  • status: todo, in-progress, blocked, done
  • priority: low, medium, high, urgent
  • tags: Array of tags
  • assignee: User assigned to the todo
  • dueDate: Due date in ISO 8601 format
  • description: Detailed description
  • dependencies: Array of todo IDs this depends on
  • subtasks: Array of subtasks
  • comments: Array of comments

Data Model

Directory-Based Storage

Todos are stored in a directory structure for better scalability, artifact support, and reduced merge conflicts:

todos/
├── tasks/                          # Primary storage
│   ├── {task-id}/
│   │   ├── task.json              # Todo metadata
│   │   ├── README.md              # Long descriptions (>300 chars)
│   │   └── artifacts/             # Attached files (future)
│   └── {task-id-2}/
│       └── task.json
├── by-project/                     # Symlink views
│   ├── work/
│   │   └── {task-id} → ../../tasks/{task-id}/
│   └── personal/
│       └── {task-id} → ../../tasks/{task-id}/
├── by-status/
│   ├── todo/ → ../../tasks/{task-id}/
│   ├── in-progress/
│   ├── blocked/
│   └── done/
├── by-priority/
│   ├── urgent/
│   ├── high/
│   ├── medium/
│   └── low/
├── by-tag/
│   └── {tag}/ → ../../tasks/{task-id}/
└── by-assignee/
    └── {user}/ → ../../tasks/{task-id}/

Todo JSON Structure

Each task.json file contains:

{
  "id": "uuid",
  "text": "Task description",
  "status": "todo",
  "priority": "medium",
  "project": "work",
  "tags": ["backend", "urgent"],
  "assignee": "user-id",
  "createdBy": "user-id",
  "createdAt": "ISO8601",
  "modifiedAt": "ISO8601",
  "dueDate": "ISO8601",
  "completedAt": "ISO8601",
  "dependencies": ["todo-id"],
  "subtasks": [{"id": "uuid", "text": "Subtask", "completed": false}],
  "comments": [{"id": "uuid", "user": "user-id", "text": "Comment", "timestamp": "ISO8601"}],
  "fieldTimestamps": {
    "text": "ISO8601",
    "status": "ISO8601"
  }
}

Benefits

  • Artifact Support: Store images, documents, and files alongside tasks
  • Reduced Conflicts: Per-task files minimize merge conflict scope
  • Scalability: Handles 10,000+ tasks efficiently
  • Flexible Organization: Multiple views via symlinks (by project, status, priority, tags, assignee)
  • Rich Metadata: Support for README.md files for detailed descriptions
  • Git-Friendly: Granular diffs and clear history

Automatic Migration

If you have an existing todos.json file, it will be automatically migrated to the directory structure on first use:

  • Creates backup as todos.json.backup
  • Converts all todos to directory format
  • Rebuilds all symlink views
  • Commits migration to Git
  • Zero data loss guaranteed

Conflict Resolution

The system uses a Last-Write-Wins (LWW) strategy at the field level:

  • Each field has its own timestamp in fieldTimestamps
  • When conflicts occur, the field with the most recent timestamp wins
  • Non-conflicting fields are merged from both versions
  • Per-file resolution: Conflicts are resolved at the individual task.json level, not globally
  • README.md conflicts use modification time from the task's modifiedAt field

Development

Running Tests

# All tests
npm test

# Unit tests only
npm run test:unit

# Integration tests
npm run test:integration

# Test coverage
npm run test:coverage

# Watch mode
npm run test:watch

Project Structure

/our_todo/
├── src/
│   ├── index.ts                 # MCP server entry point
│   ├── server/
│   │   └── MCPServer.ts         # MCP tool handlers
│   ├── api/                     # API server for web interface
│   │   ├── server.ts            # Express server
│   │   ├── mcpClient.ts         # MCP client for stdio communication
│   │   └── routes/
│   │       └── todos.ts         # Todo REST API endpoints
│   ├── git/
│   │   ├── GitManager.ts        # Git operations
│   │   ├── ConflictResolver.ts  # LWW merge logic
│   │   └── SyncManager.ts       # Sync coordination
│   ├── data/
│   │   ├── TodoRepository.ts    # Todo CRUD operations
│   │   ├── DirectoryManager.ts  # Task directory operations
│   │   └── SymlinkManager.ts    # Symlink view management
│   └── types/
│       └── Todo.ts              # Todo types and validation
├── web/                         # Svelte 5 web frontend
│   ├── src/
│   │   ├── lib/
│   │   │   ├── components/      # Svelte components
│   │   │   │   ├── KanbanBoard.svelte
│   │   │   │   ├── KanbanColumn.svelte
│   │   │   │   ├── TodoCard.svelte
│   │   │   │   └── FilterBar.svelte
│   │   │   ├── stores/          # Svelte stores
│   │   │   │   └── todos.svelte.ts
│   │   │   └── types/           # TypeScript types
│   │   │       └── Todo.ts
│   │   ├── App.svelte           # Main app component
│   │   └── main.ts              # App entry point
│   ├── package.json
│   └── vite.config.ts           # Vite configuration
├── tests/
│   ├── unit/                    # Unit tests
│   ├── integration/             # Integration tests
│   └── performance/             # Performance benchmarks
├── docs/
│   ├── adr/                     # Architecture Decision Records
│   └── releases/                # Release notes
└── dist/                        # Compiled JavaScript

Example todo repository structure (~/my-todos/):
todos/
├── tasks/
│   └── {task-id}/
│       ├── task.json
│       ├── README.md (optional)
│       └── artifacts/ (future)
├── by-project/
├── by-status/
├── by-priority/
├── by-tag/
└── by-assignee/

Test Coverage

Current test coverage: ~94%

  • Todo Model: 100%
  • ConflictResolver: 100%
  • GitManager: 100%
  • TodoRepository: 100%
  • SyncManager: 70% (timing-related test issues)
  • MCPServer: 56% (partial implementation)
  • API Server: 100%
  • MCP Client: 100%
  • Svelte Components: 100% (KanbanBoard, KanbanColumn, TodoCard, FilterBar)
  • Todo Store: 100%

Troubleshooting

Kanban Board Issues

API Server not connecting to MCP server

  • Ensure the MCP server is built: npm run build
  • Check that dist/index.js exists
  • Verify environment variables are set correctly
  • Check API server logs for errors

Web frontend can't connect to API

  • Ensure API server is running on port 3001
  • Check CORS settings if running on different ports
  • Verify the Vite proxy configuration in web/vite.config.ts

Port already in use

  • Change the port: PORT=3002 npm run start:api
  • Update CORS_ORIGIN if needed: CORS_ORIGIN=http://localhost:31415
  • Kill the process using the port: lsof -ti:3001 | xargs kill

Todos not syncing between interfaces

  • Ensure both Claude Desktop config and API server use the same TODO_REPO_PATH
  • Check that the Git repository exists at the specified path
  • Verify file permissions on the todo repository

Sync Failures

If sync fails:

  1. Check network connection
  2. Verify Git credentials
  3. Pull manually: cd ~/my-todos && git pull
  4. Check for merge conflicts

Permission Issues

Ensure the MCP server has read/write access to:

  • Todo repository path
  • Git configuration

Debug Mode

MCP Server (Claude Desktop)

  • View server logs in Claude Desktop's developer console or check stderr output

API Server

  • Set NODE_ENV=development for detailed logging
  • Check console output for request logs and errors
  • Use browser DevTools Network tab to inspect API calls

Documentation

Comprehensive documentation is available in the docs/ directory:

  • - Quick start guide for running the kanban board
  • - Migration guide from legacy todos.json to directory structure
  • - Configuration and usage examples for Claude Code and Claude Desktop
  • - Testing instructions and scenarios
  • - Known testing limitations with Svelte 5 runes
  • - Version history and release notes
  • - Architecture Decision Records
    • - Directory-Based Persistence Architecture
  • - Detailed release notes for each version

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Write tests first (TDD)
  4. Implement features
  5. Ensure all tests pass
  6. Submit a pull request

License

MIT

Acknowledgments

Built with:

Support

For issues and questions, please open an issue on GitHub.