tasq
Allows starting GitHub Copilot CLI sessions linked to tasks for AI-assisted development.
Opens new iTerm2 tabs to start or resume AI agent sessions for tasks.
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., "@tasq add a task: review PR #42"
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.
tasq
A local-first task manager, exposed as a CLI, an interactive TUI, and a local MCP server, backed by a single SQLite file. Built with Python, uv, Typer, Textual, and the MCP SDK.
See spec.md for the original design and rationale.
What it does
tasq keeps your work in one SQLite file on your machine — no account, no server,
no sync — and lets you drive it three ways over the same engine: type commands
(tasq …), scroll an interactive board (tasq ui), or let an AI assistant manage
tasks through the built-in MCP server. Anything you do one way is immediately
visible in the others.
The mental model. A task has a title, a status, a priority (P1–P5), an optional t-shirt size (XS–XL, used for effort estimates), optional scheduled (start) and due dates, a markdown description, and any number of labels. Tasks can be grouped under a project and broken into one level of sub-tasks. Every status change is recorded as an auditable history — you can always see when and why a task moved, not just where it is now.
What you can do with it:
Capture & organise — add tasks with priority, size, dates, labels, and rich descriptions; group them by project; break them into sub-tasks.
Track a lifecycle — move tasks through waiting → in-progress → blocked → done/cancelled, each transition logged with an optional comment.
See what's next — an agenda (overdue + today + upcoming) with effort estimates, and a proposed day-by-day plan that packs open work into your daily focus budget over working days (weekends skipped) — a suggestion, never written back to a task. Export the plan as an HTML report.
Find things — fuzzy search across titles/descriptions (typos are fine), and a references view that pulls URLs (PRs, JIRAs, docs) out of descriptions so you can jump straight to them.
Work interactively — a full-screen board (
tasq ui) to scroll, quick-edit priority/size/status, create/schedule/delete tasks, open references, and view the plan — all with the keyboard.Hand off to (and resume) AI agents — link a task to the AI coding session you worked on it in (agent, directory, session id, launcher/profile), then resume or start that session in a new iTerm2 tab — a fresh session is primed with a task briefing so the agent self-manages via tasq. Configurable launchers and project directories make this a one-key action.
Be legible to an AI — the MCP server exposes every capability as a tool, and labels carry human-written descriptions so an assistant acts on intent, not guesswork.
Nothing leaves your machine: it's a single local SQLite file (WAL + FTS5), and the CLI, TUI, and MCP server are thin adapters over one shared core.
Related MCP server: taskdog-mcp
Quickstart
Install with uv:
uv sync
uv run tasq --help # or symlink the ./tasq wrapper onto your PATHSee it populated in seconds — seed a throwaway demo database (it never touches your real tasks) and open the board:
uv run tasq demo --ui # seeds a demo.db and opens `tasq ui`
# …or explore piece by piece:
tasq demo # prints the exact commands to try (agenda, plan, …)Start using it for real:
tasq add "Write the launch post" -p blog --priority 2 --due 2026-08-20
tasq ui # your board (1-5 = priority · n = new · ! = flag · a = agent)Wire it into your AI assistant — register the MCP server (see Claude Code / GitHub Copilot below) and your agent can capture, plan, and flag tasks just like you do. Then follow the AI workflow walkthrough for the full loop: start a task in an agent → it links its session and pings you when it needs a decision → you answer → resume where it left off.
Install / run
uv sync # install dependencies
uv run tasq --help # the `tasq` (and short `tq`) commandThe database lives at $XDG_DATA_HOME/tasq/tasks.db by default. Override with
--db PATH or the TASQ_DB environment variable.
CLI tour
# Capture
tasq add "Write the spec" -p acme --priority 2 --size M --due 2026-07-25 \
-l writing --desc "See [design](https://figma.com/f/abc) and https://github.com/acme/repo"
# Missing dates are guessed: start = next working day, due = a few business days later
tasq add "Follow up with infra" # e.g. start 2026-07-31 · due 2026-08-07
tasq add "Someday idea" --no-guess-dates # leave both dates unset
# See what's next
tasq agenda --days 5 # overdue + today + upcoming, with effort estimates
tasq today
tasq overdue
# Get a proposed day-by-day schedule — a suggestion, never written back to tasks
tasq plan # packs open tasks into 5h/day over 5 working days
tasq plan --days 10 --hours 6 # 10 working days at 6 focus-hours/day
tasq plan --weekends # include Sat/Sun (excluded by default)
tasq plan -o html --browser # write an HTML report and open it in the browser
tasq plan -o html --out plan.html # …or just write it to a specific file
tasq plan -p Work -p IGM # limit planning to certain projects
tasq plan -L personal # keep private (labelled) tasks out of the plan
# Interactive board: scroll the task list and quick-edit with the keyboard
tasq ui # 1-5 = priority · shift+←/→ = size · s/b/d = start/block/done
# n = new task · t = set start date · o = open refs in browser
# / = fuzzy find · ! = flag for attention · p = project filter · v = plan view
# a = start in an AI agent · x = delete
# L = references view (u = unique · / = search · b = open as HTML)
# r = reload · R = resume in iTerm
# enter = edit (shows clickable refs + AI session, has Delete)
# ⟳ = linked AI session (resumable) · ⚠ = needs attention (rings a bell)
# auto-refreshes every 5s (configurable), so agent/CLI changes just appear
# Open a task's reference URLs (PRs, JIRAs, …) in the browser
tasq open 2 # opens every URL extracted from task #2's description
tasq refs open 5 # …or open a single extracted reference by its ref-id
# Link a task to the AI session you're working in, so it can be resumed later
tasq link 2 -a claude-code -d . -s <session-id> -c claude-work
# -c is the command/alias you launched with (selects a profile)
tasq unlink 2 # drop the session link
# Start a task in an AI agent — new iTerm2 tab, primed with a task briefing (macOS)
tasq work 2 # prompts for a project dir + launcher, opens a briefed session
tasq work 2 -D igm # start in the 'igm' project dir (its default launcher)
tasq work 2 -D igm -l claude-work # …and pick one of that dir's allowed launchers
tasq work 2 --resume # resume a session instead of a new briefed one
tasq work 2 -D igm --print # print the launch command instead of opening iTerm
# Resume a linked session — opens a new iTerm2 tab, cds in, and runs the agent (macOS)
tasq resume 2 # e.g. `cd <dir> && claude-work --resume <session-id>`
tasq resume 2 --print # just print the command (no iTerm), for other terminals
# Break a task into sub-tasks (one level deep; they show in list/agenda too)
tasq add "Write migration" --parent 1 --priority 1
tasq subtasks 1 # list a task's sub-tasks
tasq edit 3 --no-parent # promote a sub-task back to top-level
tasq list --top-level # hide sub-tasks from the flat list
# Flag a task as awaiting your attention (an AI agent can do this via MCP)
tasq flag 3 -m "which auth provider — okta or auth0?" # stands out + rings a bell in the UI
tasq list --attention # everything currently flagged
tasq unflag 3 # clear it once you've answered
# Move it through its lifecycle (comment optional, recorded either way)
tasq start 1 -m "picking this up"
tasq block 1 -m "waiting on backend"
tasq done 1
tasq history 1
# Find things (fuzzy — typos are fine)
tasq search "lgin bug"
tasq refs # every extracted URL (PRs, JIRAs), newest first
tasq refs --unique # collapse duplicate URLs → one row per link + task count
tasq refs -o html --browser # write an HTML report of the references and open it
tasq refs github # …or fuzzy-search them
tasq refs open 2 # open a matched URL
# Projects & labels (labels carry AI-facing descriptions)
tasq project add acme -l globex-corp
tasq label describe deep-work --desc "Requires 2h+ focus; schedule in the morning"
tasq label list
# Pull work in from external sources (PRs to review, JIRAs, emails), deduplicated
tasq fetch reviews --org acme # PRs awaiting your review (via `gh`) → tasks, deduped
tasq fetch reviews --user octocat --print # …or just print the ingest JSON
your-fetcher | tasq ingest --source jira # any fetcher: upsert JSON by (source, external_id)
tasq list --source github-reviews # what's been synced
# re-running never duplicates; see docs/ingestion.md for the item schema + example fetchers
# Machine-readable output for any query command
tasq list --status waiting,blocked --jsonConfiguration
Planning and effort estimates are tunable via an optional TOML file at
$XDG_CONFIG_HOME/tasq/config.toml (override with TASQ_CONFIG). Everything has a
default, so the file is optional. TASQ_DAILY_HOURS overrides the daily budget for
a single run, and tasq plan --hours N overrides it per-invocation.
[planning]
daily_hours = 5 # focus hours/day for `plan`; the rest is meetings/overhead
include_weekends = false # plan Mon–Fri only (override per-run with --weekends)
projects = [] # only plan these projects (empty = all); overridable with -p
labels = [] # only plan tasks carrying one of these labels
exclude_labels = ["personal"] # keep private work out of the plan (override with -L)
[effort]
unsized_hours = 2 # assumed effort for a task with no size
[effort.size_hours] # hours per t-shirt size (drives estimates and `plan`)
XS = 0.5
S = 1
M = 2
L = 4
XL = 8
[add]
guess_dates = true # fill missing start/due when adding (override with --no-guess-dates)
due_business_days = 5 # due lands this many working days after the start date
[ui]
refresh_seconds = 5 # how often `tasq ui` polls for changes (0 disables auto-refresh)
[agents.launchers] # commands/aliases for `tasq work` (each alias can be a profile)
claude = "claude-code"
claude-work = "claude-code"
copilot = "github-copilot-cli"
# Big-project directories agents can be started in (one table per project).
# `launchers` (defaults to all) restricts what's allowed there; `default` (defaults
# to the first) is preselected. `name` defaults to the path's basename.
[[agents.project_dirs]]
name = "igm"
path = "/Users/me/IGT/Azure/repos/igm"
launchers = ["copilot", "claude-work"]
default = "copilot"
# Customise the briefing that primes a fresh `tasq work` session. Placeholders
# $id, $title, $description are filled in (use ${id} next to letters). Optional —
# omit to use the built-in briefing.
[agents]
prompt_template = """
Work on tasq task #$id: $title.
$description
Link this session to task #$id in tasq, mark it in_progress, ask me for context,
and record any relevant PR / JIRA / repo URLs as you go.
"""MCP server
Run the server over stdio:
tasq serveRegister it with an MCP client (e.g. Claude Desktop):
{
"mcpServers": {
"tasq": { "command": "uvx", "args": ["tasq", "serve"] }
}
}The examples below use
uvx tasq serve, which works once the package is published. To run from a local checkout instead, useuvwith--directory, e.g."command": "uv", "args": ["run", "--directory", "/path/to/tasq", "tasq", "serve"]. Point at a specific database with theTASQ_DBenv var if you don't want the default.
Claude Code
Add it from the terminal (project-scoped):
claude mcp add tasq -- uvx tasq serve…or commit a .mcp.json at the repository root so the whole team gets it:
{
"mcpServers": {
"tasq": {
"command": "uvx",
"args": ["tasq", "serve"],
"env": { "TASQ_DB": "${HOME}/.local/share/tasq/tasks.db" }
}
}
}GitHub Copilot (VS Code)
Copilot's agent mode reads MCP servers from .vscode/mcp.json (note the
top-level servers key and the type field):
{
"servers": {
"tasq": {
"type": "stdio",
"command": "uvx",
"args": ["tasq", "serve"],
"env": { "TASQ_DB": "${env:HOME}/.local/share/tasq/tasks.db" }
}
}
}Then open the Copilot Chat Agent view and enable the tasq tools. (User-level
config lives under "mcp": { "servers": { … } } in VS Code settings.json.)
It exposes tools (add_task, edit_task, get_task, list_tasks,
search_tasks, search_references, transition_task, flag_attention,
clear_attention, link_session, unlink_session, ingest, agenda, plan,
project/label management) and resources
(task://{id}, agenda://today, agenda://upcoming, labels://). Labels are
surfaced with their descriptions, so an assistant knows what each means and
when to apply it. The agent has full read/write access.
Linking a session: link_session(task_id, agent, directory, session_id, launcher)
records which AI CLI worked on a task, where, under which session id, and with
which command/alias (so a resume can pick the right profile). Ask the agent to
"link this session to task #N" and it stores the details for later resumption.
Asking for your attention: when an agent needs a decision or input, it calls
flag_attention(task_id, note). The task then stands out (a ⚠ row) and rings a
bell in your open board — which auto-refreshes — so you notice without watching the
terminal. clear_attention(task_id) removes the flag once you've responded.
Documentation
AI workflow walkthrough — the full loop: start a task in an agent, get pinged when it needs a decision, and resume where it left off.
Ingesting external tasks — pull in PRs/JIRAs/emails as deduplicated tasks (the item schema, upsert semantics, and example fetchers).
spec.md — the original design and rationale (historical: it predates the TUI and the AI-session features, which have since shipped).
Try
tasq demofor a populated database to explore hands-on.
Architecture
The CLI and MCP server are thin adapters over a shared core:
tasq.cli ─┐
├─▶ tasq.services.Core ─▶ tasq.repository ─▶ SQLite
tasq.mcp ─┘ (use cases) (typed rows)models.py— enums + frozen, fully-typed dataclasses (the domain objects).repository.py— the only place that touchessqlite3rows.services.py— use cases, transactions, and domain rules.references.py/search.py— URL extraction and fuzzy (FTS5 + rapidfuzz) search.serialize.py— one shared dict shape for CLI--jsonand MCP output.
Development
uv run pytest # tests
uv run mypy # strict type checking
uv run ruff check . # lint
uv run ruff format . # formatAvailable Tools
19 toolsadd_projectC
Create a project. Project labels describe the project (e.g. the company).
Inputs: name (required), labels, description. Returns: object
add_taskA
Create a task. priority is 1 (highest)–5; size is XS/S/M/L/XL;
dates are ISO 'YYYY-MM-DD'; project is a project name (created if new).
Pass parent_id to make this a sub-task (nesting is limited to one level).
When guess_dates is true (default), a missing start date defaults to the
next working day and a missing due date to a few business days later; pass
false to leave dates unset.
Inputs: title (required), size, labels, project, +6 more. Returns: object
agendaC
Overdue, today, upcoming (next N days), and in-progress/blocked tasks.
Inputs: days. Returns: object
archive_projectA
Archive a project (kept, not deleted).
Inputs: name (required). Returns: object
clear_attentionA
Clear a task's 'needs attention' flag once the user has responded.
Inputs: task_id (required). Returns: object
describe_labelA
Set or update a label's description (creates the label if new).
Inputs: name (required), description (required). Returns: object
edit_taskA
Update a task. Omit a field to leave it unchanged; pass an empty string
to clear an optional field (description, project, size, dates). Set
parent_id to re-parent (one level max), or clear_parent=true to detach.
Inputs: task_id (required), size, title, labels, +7 more. Returns: object
flag_attentionA
Flag a task as awaiting the user's attention — e.g. you need a decision
or input to proceed. note should say what you need (a short question).
This makes the task stand out and rings a bell in the user's interactive
board. Call clear_attention once the user has responded.
Inputs: task_id (required), note. Returns: object
get_taskC
Full task detail including status history and extracted references.
Inputs: task_id (required). Returns: object
ingestA
Sync external items into tasks, deduplicated by (source, external_id).
Each item needs 'external_id' (the stable dedup key within `source`) and
'title'; optional: description, url, project, labels, priority (1–5), size,
scheduled_date, due_date (ISO). Re-running upserts instead of duplicating:
new items are created, existing non-terminal ones have their title/description
refreshed (your triage is kept), terminal ones are left alone. With
`close_missing`, previously-ingested tasks absent from this batch are completed.Inputs: items (required), source (required), labels, project, +1 more. Returns: object
link_sessionA
Link the AI agent session you're working in to a task, so it can be
resumed later. agent is 'claude-code' or 'github-copilot-cli';
directory is the absolute working directory of this session; session_id
is this session's own id (used with --resume) if you know it; launcher is
the command or shell alias used to start the agent (it selects the profile,
e.g. 'claude-work') — omit to use the agent's default command. Re-linking
replaces any previous link. Call this when you start or resume work on a task.
Inputs: agent (required), task_id (required), directory (required), launcher, +1 more. Returns: object
list_labelsA
List labels WITH descriptions — read these to know what each label means and when to apply it before labelling or prioritising.
Inputs: no named parameters. Returns: result
list_projectsD
List projects.
Inputs: include_archived. Returns: result
list_tasksB
List tasks with structured filters. By default terminal tasks
(completed/cancelled) are hidden unless include_terminal is true. Use
parent_id for one task's sub-tasks, or top_level_only to hide sub-tasks.
Inputs: sort, sizes, labels, overdue, +9 more. Returns: result
planA
Propose a non-persistent day-by-day schedule of open tasks, greedily
packed into a daily focus budget (default from config) and ordered by
started-then-priority-then-due. Counts working days — weekends are skipped
unless include_weekends. Narrow the candidates with projects/labels
(include) or exclude_labels (drop private work); each falls back to config.
The suggested day is not saved to the task.
Inputs: days, labels, projects, capacity_hours, +2 more. Returns: object
search_referencesB
Search URLs extracted from task descriptions (fuzzy on url + anchor).
Inputs: limit, query, domain, task_id. Returns: result
search_tasksA
Fuzzy-search tasks over title and description; ranked, best first.
Inputs: query (required), limit. Returns: result
transition_taskA
Change a task's status, recording the transition (comment optional). Statuses: waiting, in_progress, blocked, completed, cancelled.
Inputs: task_id (required), to_status (required), comment. Returns: object
unlink_sessionA
Remove the AI session link from a task.
Inputs: task_id (required). Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 19 tools
Each tool targets a distinct resource and action: tasks, projects, labels, sessions, attention flags, and bulk ingestion. Overlap is minimal, and descriptions clearly distinguish search_tasks from search_references and agenda from plan.
Most tools follow a clear verb_noun pattern (add_task, list_tasks, edit_task, link_session). A few exceptions like 'ingest', 'agenda', and 'plan' deviate from this pattern but remain readable and predictable.
With 19 tools covering task CRUD, status transitions, projects, labels, sessions, and planning, the count is well-scoped for the server's purpose. It is neither overly sparse nor bloated.
The surface covers most lifecycle needs: create/read/update/transition tasks, manage projects and labels, link sessions, and flag attention. Minor gaps exist, such as no hard delete for tasks and no session listing, but these are workable.
Related MCP Connectors
Local-first task manager: create, edit, and complete tasks, projects, and checklists via MCP.
Task management your AI agents can actually run. One line becomes a context-ready task over MCP.
Simple, fast todo app: manage tasks, projects and tags from Claude and other MCP clients.
Task & board management for AI agents + humans. Kanban, comments, digests via MCP.
Related MCP Servers
- AlicenseAqualityDmaintenanceAn MCP server that enables AI assistants to interact with the Taskwarrior command-line task management tool. It allows users to list, create, modify, and organize tasks using projects, tags, and annotations through natural language.132MIT
- AlicenseAqualityAmaintenanceLocal-first task management with CLI, TUI, and REST API. MCP server enables Claude to manage tasks, track time, optimize schedules, and handle dependencies.26361MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage tasks with full lifecycle support including due dates, priorities, tags, subtasks, and project lists via 19 SQLite-backed MCP tools.4-
- AlicenseAqualityDmaintenanceA task-based AI orchestrator that bridges AI models (Gemini, Claude, OpenAI) with local environments, operating as an interactive CLI and an MCP server for structured autonomous development.218 npmMIT