Skip to main content
Glama
README.md
# TaskFlow MCP

A small [Model Context Protocol](https://modelcontextprotocol.io) server that
gives an AI coding agent (Claude Code, Claude Desktop, or any other MCP
client) direct read/write access to a task tracker, backed by SQLite.

I built this after using Claude Code to run a job-application pipeline and
wanting the same thing for my own projects: a lightweight board an agent can
query and update mid-conversation, without a browser tab or a hosted
project-management tool in the way.

## What it exposes

**Tools**

| Tool | Description |
|---|---|
| `add_task` | Add a task with a title, optional priority (`low`/`medium`/`high`), and optional notes. |
| `list_tasks` | List tasks, optionally filtered by `status` and/or `priority`. |
| `update_task_status` | Move a task between `todo`, `in_progress`, and `done`. |
| `delete_task` | Remove a task permanently. |

**Resources**

| URI | Description |
|---|---|
| `tasks://board` | The whole board rendered as a markdown checklist, grouped by status. |

## Install

```bash
git clone https://github.com/SyedFrazAli/taskflow-mcp.git
cd taskflow-mcp
pip install -e ".[dev]"
```

## Run the tests

```bash
pytest
```

17 tests cover the SQLite layer (`tests/test_db.py`) and the MCP tool/resource
handlers (`tests/test_server.py`), including validation errors and the
empty-board edge case.

## Use it from Claude Desktop or Claude Code

Add it to your MCP client config (for Claude Desktop, that's
`claude_desktop_config.json`; Claude Code uses the same shape):

```json
{
  "mcpServers": {
    "taskflow": {
      "command": "python",
      "args": ["-m", "taskflow_mcp.server"],
      "env": {
        "TASKFLOW_DB_PATH": "/absolute/path/to/taskflow.db"
      }
    }
  }
}
```

Restart the client, and it can then call `add_task`, `list_tasks`,
`update_task_status`, and `delete_task`, or read the `tasks://board` resource
to see the current state as markdown.

## Design notes

- The SQLite layer (`db.py`) has no dependency on the `mcp` package, so it is
  unit tested directly, without a client/server round trip.
- The server layer (`server.py`) is a thin adapter: it validates nothing
  itself and instead lets `db.py` raise `InvalidTaskFieldError` /
  `TaskNotFoundError`, which it turns into an `Error: ...` text response
  rather than letting the MCP transport see an unhandled exception.
- `TaskStore(":memory:")` is used throughout the test suite so tests never
  touch disk or leave a `taskflow.db` file behind.

## License

MIT — see [LICENSE](LICENSE).