todokit-mcp
An MCP server for Todokit, a task management and productivity tool with JSON storage.
One-Click Install
Features
- Task management: add, update, complete, and delete todos.
- Batch operations: add multiple todos at once.
- Safe listing: status-based filtering with a default of pending-only and truncation to keep responses small.
- JSON persistence with queued writes and atomic file writes.
- Optional diagnostics events (tool calls/results, storage, lifecycle) via Node diagnostics channels.
Quick Start
npx -y @j0hanz/todokit-mcp@latest
The server runs over stdio (no HTTP endpoint) and registers MCP tools on startup.
Installation
NPX (recommended)
npx -y @j0hanz/todokit-mcp@latest
Global install
npm install -g @j0hanz/todokit-mcp
Then run:
todokit-mcp
From source
git clone https://github.com/j0hanz/todokit-mcp-server.git
cd todokit-mcp-server
npm install
npm run build
npm start
Configuration
Storage path
By default, todos are stored in todos.json in the current working directory. To control where data is written, set the TODOKIT_TODO_FILE environment variable to an absolute or relative path ending with .json. Relative paths resolve from the current working directory. The directory is created as needed; if the file does not exist, the server starts with an empty list.
When all todos are completed, the server removes the storage file so it does not linger on disk.
Examples:
# macOS/Linux
TODOKIT_TODO_FILE=/path/to/todos.json npx -y @j0hanz/todokit-mcp@latest
# Windows PowerShell
$env:TODOKIT_TODO_FILE = 'C:\path\to\todos.json'
npx -y @j0hanz/todokit-mcp@latest
JSON formatting
By default, todos are written as pretty-printed JSON (2-space indentation). To write compact JSON instead, set TODOKIT_JSON_PRETTY to 0 or false.
TODOKIT_JSON_PRETTY=0 npx -y @j0hanz/todokit-mcp@latest
CLI options
The server accepts a few CLI flags (use -- to forward args when running via npx).
npx -y @j0hanz/todokit-mcp@latest -- --todo-file ./todos.json --diagnostics --log-level debug
| Flag | Alias | Description |
|---|---|---|
--todo-file | -f | Override the todo storage path (same as TODOKIT_TODO_FILE). |
--diagnostics | -d | Enable diagnostics output (JSON lines) to stderr. |
--log-level | -l | Diagnostics log level: error, warn, info, debug (default: info). |
The log level is only used when diagnostics output is enabled.
Diagnostics
Diagnostics events are always published on Node's diagnostics_channel and can be subscribed to programmatically. When --diagnostics is set, the server attaches default subscribers and prints JSON events to stderr (stdout stays reserved for MCP traffic).
Channels:
todokit:tool— tool call + tool result eventstodokit:storage— read/write/close eventstodokit:lifecycle— shutdown events
Tools
All tools return a JSON payload in both content (stringified) and structuredContent.
Inputs are validated with strict Zod schemas, so unknown fields are rejected.
Success payload:
{
"ok": true,
"result": {}
}
Error payload:
{
"ok": false,
"error": { "code": "E_CODE", "message": "Details" }
}
The result shape is tool-specific.
add_todo
Create a new todo item.
| Parameter | Type | Required | Description |
|---|---|---|---|
| description | string | Yes | Description of the todo (1-2000 chars) |
| priority | string | Yes | Priority: low, medium, high |
| category | string | Yes | Category: work, bug, testing, docs |
| dueAt | string | No | Optional due date/time as an ISO 8601 timestamp with offset (RFC3339) |
Result fields:
item(todo)summarynextActions
add_todos
Add multiple todo items in one call.
Parameters:
items(array, required): Array of todo objects (1-50 items). Each item supportsdescription,priority,category,dueAt.
Result fields:
items(todos)summarynextActions
list_todos
List todos with an optional status filter.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| status | string | No | pending | Filter by status: pending, completed, all |
Notes:
- Results may be truncated for safety (currently returns up to 50 items). Use
status: "pending"(default) orstatus: "completed"to narrow the response.
Result fields:
items(todos)summarycounts(total,pending,completed) — global counts across all todosfilteredCounts(total,pending,completed) — counts within the requested status filterstatus(the effective status filter)returned,truncated,remaining,hint
update_todo
Update fields on a todo item.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | The ID of the todo to update |
| description | string | No | New description (1-2000 chars) |
| priority | string | No | New priority: low, medium, high |
| category | string | No | New category: work, bug, testing, docs |
| dueAt | string | No | Replace due date/time (ISO 8601 with offset) |
Notes:
- If no updatable fields are provided, the tool returns an error.
Result fields:
item(todo)summarynextActions
complete_todo
Mark a todo as completed.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | The ID of the todo |
Result fields:
item(todo)summarynextActions
delete_todo
Delete a todo item by ID.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | The ID of the todo to delete |
Result fields:
deletedIds(array)summarynextActions
Data Model
A todo item has the following shape:
{
"id": "string",
"description": "string",
"completed": false,
"priority": "low|medium|high",
"category": "work|bug|testing|docs",
"dueAt": "ISO timestamp with offset?",
"createdAt": "ISO timestamp with offset",
"updatedAt": "ISO timestamp with offset?",
"completedAt": "ISO timestamp with offset?"
}
Notes:
createdAt,updatedAt, andcompletedAtare ISO 8601 timestamps with offset (e.g.,2025-02-28T10:30:00Z).dueAtuses the same ISO 8601 timestamp format with an explicit offset.- When tools report an ambiguous match (error code
E_AMBIGUOUS), prefer using an exactidfrom the provided candidates.
Client Configuration
VS Code
Add this to your mcpServers configuration in settings.json:
{
"todokit": {
"command": "npx",
"args": ["-y", "@j0hanz/todokit-mcp@latest"]
}
}
Claude Desktop
Add this to your claude_desktop_config.json:
{
"mcpServers": {
"todokit": {
"command": "npx",
"args": ["-y", "@j0hanz/todokit-mcp@latest"]
}
}
}
Cursor
- Go to Cursor Settings > Features > MCP
- Click + Add New MCP Server
- Name:
todokit - Type:
command - Command:
npx -y @j0hanz/todokit-mcp@latest
Development
Prerequisites
- Node.js >= 20.0.0
Scripts
| Command | Description |
|---|---|
| npm run build | Compile TypeScript to JavaScript |
| npm run dev | Run server in watch mode for development |
| npm start | Run the built server |
| npm run test | Run unit tests (node --test + tsx) |
| npm run test:coverage | Run unit tests with coverage |
| npm run lint | Run ESLint |
| npm run format | Format with Prettier |
| npm run format:check | Check formatting with Prettier |
| npm run type-check | Run TypeScript type checking |
| npm run dup-check | Run duplicate code checks (jscpd) |
| npm run clean | Remove the dist/ build output |
| npm run inspector | Launch the MCP inspector (pass server cmd after --) |
Manual verification
npm run build
npm run inspector -- node dist/index.js
Project structure
src/
index.ts # MCP server entrypoint (stdio)
tools.ts # Tool registrations and handlers
schema.ts # Zod input/output schemas
storage.ts # JSON persistence and CRUD
responses.ts # Tool response builders
diagnostics.ts # Node diagnostics channels
tests/ # Unit tests
docs/ # Assets (logo)
Contributing
Contributions are welcome. Please run npm run format, npm run lint, npm run type-check, npm run build, npm test, npm run test:coverage, and npm run dup-check before opening a PR.
License
This project is licensed under the MIT License - see the LICENSE file for details.
