mcp-tasks-server
README.md
# mcp-tasks-server
A small **Model Context Protocol** server that exposes a personal task tracker
to any MCP-compatible client (Claude Desktop, Claude Code, custom agents).
Tasks live in a local SQLite database; no cloud, no surprises.
This is a reference implementation of an MCP server that takes **real
write-actions** on persistent state — the kind of integration you build
between an agentic AI platform and an enterprise system, scaled down to a
laptop.
## Tools exposed
| Tool | Effect on state |
|-------------------------|-----------------|
| `add_task` | Insert a new task |
| `list_tasks` | Read; optional status filter |
| `complete_task` | Update `status='done'` |
| `delete_task` | Hard-delete a task |
| `summarize_by_status` | Read; aggregate counts |
Each tool has a JSON schema declared in code, validated on every call.
## Quick start
```bash
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python server.py
```
### Wire into Claude Desktop
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"tasks": {
"command": "python",
"args": ["/absolute/path/to/server.py"]
}
}
}
```
Then restart Claude Desktop. The tools appear in the MCP picker.
## Sandbox / safety notes
- Database file lives at `~/.local/share/mcp-tasks/tasks.db` by default;
override with `MCP_TASKS_DB`. The path is normalized and confined to the
user's home directory.
- `delete_task` requires the task ID to be an integer; no SQL is built from
string concatenation. All queries use parameterized statements.
- The server has no network listeners — communication is over stdio per the
MCP spec.
## Sample tool calls
The full request/response shapes for every tool are in
[`examples/tool-call-examples.md`](./examples/tool-call-examples.md).
Highlights:
| Tool | Example call | Example result |
|------|--------------|----------------|
| `add_task` | `{"title": "Review RFC", "notes": "..."}` | `{"id": 1, "title": "...", "status": "open"}` |
| `list_tasks` | `{"status": "open"}` | `{"tasks": [...]}` |
| `complete_task` | `{"id": 1}` | `{"id": 1, "status": "done"}` |
| `summarize_by_status` | `{}` | `{"counts": {"open": 2, "done": 1}}` |
## Design notes
- **Why SQLite?** Embedded, transactional, present on every Python install. A
real enterprise integration would target a service API; the contract on the
agent side is identical.
- **Why explicit JSON schemas?** Some MCP clients display the schemas to the
user before approving a tool call. Putting them inline in the server makes
tool surfaces self-documenting and gives the LLM unambiguous parameter
contracts.
- **Why no auth?** Personal/local server. For an enterprise MCP server you'd
add OIDC token verification at the tool boundary and scope each tool to
the calling principal's permissions.
## License
MIT — see `LICENSE`.
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues