todo-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@todo-mcpList my current tasks and show the next one"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
todo-mcp
An MCP server whose store is a TODO.md you can read, edit and diff by hand. Writes are
byte-range splices, so the file stays yours: hand-authored tables, tab indentation and any
prose outside a task are never re-serialised.
Speaks stdio for MCP clients and Streamable HTTP for everything else.
Credit
Based on CalamityAdam/mcp-todo, which supplied
the original scaffold: the createTodoMcpServer factory shape, the Express Streamable HTTP
wrapper and the session handling.
Almost nothing else survives. That version kept todos as numbered records in a JSON blob at
~/.mcp-todos.json with three tools over { id, title, done }. This one replaces the store
with a markdown document, swaps numeric ids for slugs, and grows the tool surface to seven
with statuses, areas, reference breadcrumbs, dated log notes, full-text query and
duplicate detection. The two projects no longer share an implementation.
Upstream ships no LICENSE file; its package.json declares ISC, which is what this repo
carries forward.
Related MCP server: MCP Project Manager
Install
Run it straight from GitHub, no clone:
npx github:adrianhardy/todo-mcpAfter pushing any changes, use npx --ignore-existing github:adrianhardy/todo-mcp to pick them up.
For regular use, install once and forget about it:
npm i -g github:adrianhardy/todo-mcp
todo-mcpEither route builds from source on install via the prepare script, so dist/ is never
committed. Node 20 or newer.
Usage
todo-mcp starts the HTTP server by default, because that is the useful thing to do
when a person runs it in a terminal. Set MCP_STDIO=1 to speak stdio instead, which is
what an MCP client spawning it as a subprocess wants.
With an MCP client
{
"mcpServers": {
"todo": {
"command": "npx",
"args": ["-y", "github:adrianhardy/todo-mcp"],
"env": { "MCP_STDIO": "1" }
}
}
}Installed globally, that becomes "command": "todo-mcp" with the same env block.
The working directory decides which file you get. TODO_FILE resolves against the
process's cwd and defaults to TODO.md, so a client launched in a project edits that
project's todo list. Set TODO_FILE to an absolute path if you want one shared list
regardless of where the server starts.
Over HTTP
PORT=8080 TODO_MCP_TOKEN=$(openssl rand -hex 32) todo-mcpPOST /mcp- JSON-RPC requestsGET /mcp- SSE stream for server notificationsDELETE /mcp- end the session
Setting TODO_MCP_TOKEN requires Authorization: Bearer <token> on all three. Leaving it
unset disables authentication, which is fine on localhost and nowhere else.
Configuration
variable | default | meaning |
|
| store path, resolved against cwd |
| unset |
|
|
| HTTP port |
| unset | bearer token; unset means no auth |
A .env file is read if present. See .env.example.
Storage
TODO.md is the store, not a JSON blob. The file is the record: readable, editable by
hand, and diffable in git.
A task is a ## section. Fields the server owns live in a comment block directly under
the heading; everything below it is prose the human owns.
## Feature Idea version two: the new widget which tracks things
<!-- todo
id: feature-idea-version-two
area: inventory
status: next
refs: [./src/do_stuff.ts, ClassName.Method, OtherClassName]
created: 2026-08-19
updated: 2026-08-22
-->
**Next step:** close the ledger. ClassName.Method uses 0.25 and it needs 17.2%.
**Already known:** ...
### Log
- 2026-08-22 Slab_Wall_1x3 not started; parade places 24 of those to every 6 of the 3x3.Ids are slugs, not numbers, so they survive reordering and deletion. File order is priority order, which is why there is no priority field.
Writes are byte-range splices: a mutation rewrites only the span it owns. Hand-authored tables, tab indentation and any prose outside a task section are never re-serialised, so they cannot be reflowed or lost. Handlers are serialised through a lock, because two interleaved read-modify-write cycles would splice against offsets that no longer describe the file.
Design
list is abbreviated
list_todosreturns a one-line index and never task bodies.get_todoreturns one whole section.qorrefis the expected path; listing everything is the exception.Capture takes one field. Only
titleis required, and new tasks default to statuscaptured. A tool that demands an area and a next step at the moment something is noticed does not get used, and the file only earns its keep if things get written down as they are found. Triage movescapturedtoopen/next/parked/somedaylater.
Status values
status | meaning |
| raw, untriaged. The default for a new task. Hidden from unfiltered lists |
| real work, understood |
| up now |
| deliberately deferred; the body says why |
| aspirational |
| finished. Stays in the file for the record. Hidden from unfiltered lists |
Tools
list_todos- abbreviated index; filtersarea,status,ref,q,limitget_todo- full markdown of one task, body includedadd_todo- capture a task; onlytitlerequired. Reports possible duplicatesupdate_todo- change any field; only what is passed is rewrittenappend_note- add a dated bullet to a task's logset_status- move a task through triageremove_todo- delete a task and its prose. Preferset_status done
Resources
todos://list- one-line index of open tasks
Architecture
src/todo.ts- the markdown store: parsing, byte-range patching, query, dedupsrc/server.ts- MCP tool surface. Pure factory, no side effects on importsrc/http.ts- Streamable HTTP transport, auth and session mapsrc/cli.ts- thetodo-mcpbinary; picks a transport and starts it
This server cannot be deployed
Maintenance
Related MCP Connectors
Create, list, and complete todo items through MCP.
Local-first task manager: create, edit, and complete tasks, projects, and checklists via MCP.
Read and write Mission Control state via MCP — projects, tasks, subtasks, templates, status updates.
- mcpOAuthnet.todoist
Official Todoist MCP server for AI assistants to manage tasks, projects, and workflows.
Related MCP Servers
- AlicenseBqualityDmaintenanceManages #TODO comments in source code files, enabling you to add and query TODOs via MCP.11MIT
- FlicenseAqualityDmaintenanceEnables task management (create, list, update tasks with priority and status) using SQLite storage via MCP tools.3-
- FlicenseBqualityCmaintenanceEnables task management via MCP tools for creating, listing, updating, completing, and deleting tasks with JSON file storage.6-
- AlicenseAqualityCmaintenanceEnables managing local Markdown notes and tasks through MCP tools to create, list, read, mark as done, and delete them.5MIT