taskpod
The developer CLI and MCP server for Taskpod — the AI-native task tracker where humans and agents work the same board.
Your repo's central mind. Three commands take a bare clone to a fully wired workspace where you, your teammates, and every AI agent share one live picture of the project — tasks, sprint, dependencies, and the learnings everyone records as they work:
npx taskpod login
npx taskpod init
npx taskpod agent-setup
Then, as you work:
npx taskpod sync
This one package ships two things:
taskpod — a CLI that links a repo to a Taskpod project, syncs a live .taskpod/ context bundle to your machine and your local AI, and writes work back to the board.
taskpod mcp — an MCP server (stdio) that exposes Taskpod's tools to any MCP client (Claude Code, Cursor, etc.).
Both talk to the Taskpod REST API over HTTPS with your personal token — no database access, no secrets in your repo. No install needed (npx taskpod …), or install globally with npm i -g taskpod.
The flow
taskpod init — the repo is the project. Run inside a git repo and init reads your origin remote, asks the server to create (or find) the Taskpod project for that repo, links the repo (taskpod.json), and pulls the .taskpod/ context bundle — one command from clone to ready:
$ npx taskpod init
Detected git remote: acme/web
✓ Created web (WEB) from acme/web.
Workspace ready: WEB — 12 tasks, 3 learnings.
Run taskpod status, or taskpod agent-setup to connect your AI tools.
Run it in a teammate's clone of the same repo and it links to the same project (created: false) — the repo is the identity. --team "Name" files the project under a specific team (creating it if needed). Outside a git repo, or with an explicit --name "Project", the original flow still works: npx taskpod init --team "My Team" --name "My App" creates a named project non-interactively (agent-friendly).
At the end of a successful init on a terminal, it offers to finish the job — Connect your AI tools (Claude Code / Cursor) now? (Y/n) — and, on yes (the default), runs the same auto-detect, no-secrets code path as taskpod agent-setup. Pass --no-agents to skip the prompt; non-interactive runs (CI, agents) never prompt and just print the agent-setup hint.
taskpod agent-setup — one command connects every AI tool. Writes real MCP config for the tools it detects in your repo (flags for CI: --claude, --cursor, --codex, --all):
- Claude Code — merges a
taskpod server entry into .mcp.json (never clobbers your other servers), adds a marker-guarded TaskPod section to CLAUDE.md, and installs a real Claude Code skill at .claude/skills/taskpod/SKILL.md (valid name/description frontmatter + the full agent protocol). The skill body is fetched live from <apiBase>/skill.md (5-second timeout, TASKPOD_API_URL-aware for self-hosted instances); on any failure it falls back to the copy bundled in this package, so the install works offline. Idempotent: the file is rewritten only when its content differs.
- Cursor — same server entry in
.cursor/mcp.json.
- Anything else (Codex, Windsurf, …) — prints the command (
npx -y taskpod mcp) + skill URL.
By default no secret is written: taskpod mcp picks up your taskpod login token automatically on each machine. For CI or containers, --with-key [token] embeds env.TASKPOD_TOKEN in the config (don't commit that). Re-running updates everything in place — never duplicates.
Skill pack
agent-setup installs the TaskPod skill pack by default — a set of general engineering skills, shipped inside this package, that land in the repo's .claude/skills/<name>/ and load automatically in Claude Code:
clean-code | Write and review clean, readable code — names, functions, comments, errors, tests — with modern judgment on where the book overreaches |
design-patterns | Pick (or skip) OO design patterns by smell — KISS first, lightest form wins, patterns for likely change only |
pr-craft | How to ship — imperative one-line commit subjects, one logical change per commit, no AI attribution ever, small diffs, honest what/why/how-verified PR descriptions |
verify-your-work | Before claiming done — drive the affected flow end-to-end, verify acceptance criteria one by one, report failures and skipped steps faithfully |
decompose-to-plan | Decompose briefs into 3–6 epics × 2–6 tasks with explicit acceptance criteria, backward-only dependencies, and honest priorities — hard sub-problems get 2–3 candidate approaches with tradeoffs and a recommendation, staged WAITING_APPROVAL for the human call |
uxloom-journeys (all) | Journey-first UI/UX validation — model journeys as state machines in a JourneyGraph, then run the bundled deterministic validator (validate.mjs, no network) to 0 errors |
java-annotations (all) | Choose official Java annotations with judgment — Lombok vs records, Micrometer/Powertools instrumentation, Jakarta Validation vs JSpecify, Dagger vs Guice vs Spring |
coverage-first-review (all) | When reviewing/grading — report every finding with confidence + severity and a concrete failure scenario; never self-filter |
Usage:
npx taskpod agent-setup
npx taskpod agent-setup --with-skills=all
npx taskpod agent-setup --no-skills
The core pack installs silently — no flag, no prompt, same as the taskpod skill itself. --no-skills opts out; --with-skills=all upgrades to the full pack (--with-skills[=core] is an explicit no-op alias for the default). The install is idempotent per file (each file written only when its content differs, reported as installed/updated/unchanged), and the CLAUDE.md TaskPod section lists the installed skills so agents know they're there.
taskpod sync — the bidirectional central mind. One command keeps you and the board in lockstep:
- ↑ push — new entries in
.taskpod/learnings.md (one per ## title heading, body below; optional kind prefix like ## [gotcha] title — learning | decision | convention | gotcha), plus anything passed as --note "...", are shared to the project's learnings. Pushed entries are fingerprinted in .taskpod/.synced, so sync is idempotent and never double-posts; the outbox is consumed after pushing.
- ↓ pull — refreshes the whole
.taskpod/ bundle, including LEARNINGS.md: the project's shared memory (everyone's decisions, conventions, and gotchas) rendered for your local AI to read.
$ npx taskpod sync --note "prisma db push needed after schema changes"
✓ ↑ 2 learnings shared · ↓ context updated: 14 tasks, 5 learnings.
taskpod ingest — pre-load the central mind from an existing repo. One deterministic scan turns the knowledge already sitting in your repo into board state:
- Wiki —
README.md becomes a "Project overview" page; each docs/**/*.md (up to 15 files, ≤50 KB each) becomes a page titled by its relative path.
- Learnings — detected conventions: the stack (from
package.json deps), build/test commands (from scripts), the first lines of CONTRIBUTING.md, and any lint/format configs — plus a gotcha listing the variable names in .env.example (never values).
- Tasks —
TODO:/FIXME:/HACK: comments in source files (ts/tsx/js/py/go/rs/java/rb) become LOW-priority BACKLOG tasks with their file:line (default 20, --limit-tasks N to change).
- Resource — the git origin remote is added as a REPO resource.
The scan skips node_modules/.git/dist/build/.next, and the whole command is idempotent: docs, learnings, and tasks whose titles already exist on the board are skipped, so re-running never duplicates. --dry-run prints the full plan without writing anything. After a real run it pulls, so .taskpod/ immediately reflects the new board.
When taskpod init creates a project (not links an existing one) and the repo has a README, docs, or TODOs, it offers to run ingest right away — Pre-load the board from this repo's README, docs, and TODOs? (Y/n), default yes. Pass --no-ingest to skip the prompt; non-interactive runs never prompt and just print the hint.
CLI
Auth & link
login authorize this machine in the browser
logout remove stored credentials
whoami show the signed-in user
init [--team T --name N] create/link the project from this repo's git remote + pull
[--no-agents] skip the end-of-init "connect your AI tools" prompt
[--no-ingest] skip the end-of-init "pre-load the board" prompt
link [KEY] connect this repo to a project (writes taskpod.json)
agent-setup connect Claude Code / Cursor / any MCP client to this project
installed by default: the TaskPod skill pack into .claude/skills/
[--no-skills] skip the skill pack
[--with-skills=all] upgrade to the full pack (--with-skills[=core] is a no-op)
Context
sync [--note "..."] push new .taskpod/learnings.md entries ↑ + pull context ↓
pull sync .taskpod/ (context, board, mine, deps, resources, learnings, skill)
ingest [--dry-run] pre-load the board from this repo: README + docs/ → wiki,
[--limit-tasks N] conventions → learnings, TODO/FIXME/HACK comments → tasks (default 20)
status your tasks + board summary + sync age
mine [--blocked] just your tasks
show <ticket> full task detail
resources [--json] list this project's resources, grouped by type
setup [--clone] clone repos + list every resource to get you working
doctor health check: local git vs board drift
Work
start <ticket> [-m note] → IN_PROGRESS + checkpoint comment
done <ticket> [-m report] → IN_REVIEW + work-report comment
comment <ticket> -m ".." [-t progress|decision|blocker|handoff|question]
eta <ticket> <when> [--confidence low|med|high]
assign <ticket> --to <name|email> reassign to a human teammate
handoff <ticket> --to-agent [name] hand to an agent (needs acceptance criteria)
handoff <ticket> --to-human --needs "..." hand back to a human (Needs You)
Other
skill --install install the agent protocol into this repo
mcp [--api-key <tok>] run the MCP server on stdio (defaults to your login token)
Help is always safe. taskpod <cmd> --help (or -h) prints that command's usage lines and exits — it never executes the command, so taskpod sync --help won't sync and taskpod init --help won't create anything.
Config & credentials. A committed taskpod.json in the repo records { apiBase, projectId, projectKey }. Your token is stored separately in ~/.config/taskpod/credentials.json (mode 0600) — never in the repo. Override with TASKPOD_API_URL / TASKPOD_TOKEN.
The .taskpod/ bundle. taskpod pull/sync write context.md, board.json, mine.md, deps.md, resources.md, LEARNINGS.md (the project's shared memory), plus SKILL.md and AGENTS.md (the agent protocol) so your local AI has full, live project context. .taskpod/ is git-ignored automatically.
Resources. Each project carries a catalog of the links a human or agent needs to work on it — repos, docs, BRDs, designs, cloud consoles, dashboards, SOPs, and environments. taskpod resources lists them grouped by type; taskpod setup gets you ready to work by printing a git clone for every REPO resource (add --clone to actually run them, skipping repos already checked out) and listing the rest grouped. taskpod pull also materializes them into .taskpod/resources.md (grouped, with a clone command per repo) and a Resources section near the top of .taskpod/context.md, so an agent reading context immediately knows where everything lives.
MCP server
taskpod agent-setup writes this config for you. To wire it by hand: if you've run taskpod login, no key is needed — taskpod mcp uses your stored login token automatically:
claude mcp add taskpod -- npx -y taskpod mcp
Or point any MCP client at the stdio server with an explicit token:
// .mcp.json (Claude Code) or your client's MCP config
{
"mcpServers": {
"taskpod": {
"command": "npx",
"args": ["-y", "taskpod", "mcp", "--api-key", "tp_live_xxx"]
}
}
}
Create a token in Taskpod under Settings → API Access. Auth precedence: --api-key > API_KEY env > TASKPOD_TOKEN env > ~/.config/taskpod/credentials.json (written by taskpod login).
The server exposes the full Taskpod toolset — teams, projects, folders, tasks, comments, subtasks, dependencies, lifecycle, and handoff — plus the workspace + resource tools below.
Workspace: the agent-native entry point
The four tools an agent needs to bootstrap and stay grounded in a repo:
init_workspace({ repoUrl? | repoFullName?, teamId?, name? }) — create (or find) the Taskpod project for a git repository. The repo is the project's identity: calling it twice for the same repo returns the same project (created: false).
sync_context({ projectId }) — returns a compact digest ready to inject into working context: project, active sprint + goal, task counts, active tasks by status with owners, recent learnings, and wiki page titles.
record_learning({ projectId, kind?, title, content }) — write a learning | decision | convention | gotcha to the project's shared memory, so every human (taskpod sync) and agent (sync_context) sees it on their next pull.
search_knowledge({ query }) — search the team's existing tasks, wiki docs, and learnings across all your projects, returned as a compact digest (tickets with status + project, doc titles, learning excerpts). Reuse before build: call it before designing or implementing anything new — someone (human or agent) may already have solved it, decided it, or written down why not to.
There is deliberately no ingest_workspace MCP tool: the hosted MCP server has no access to your repo's files, so it can't scan them for you. taskpod ingest is the CLI's repo-side scanner; an agent working inside the repo achieves the same result with its own file access plus create_doc, record_learning, and create_task (the decompose-to-plan path).
Resource catalog
list_project_resources({ projectId }) — list a project's repos, docs, BRDs, designs, consoles, dashboards, SOPs, and environments.
add_project_resource({ projectId, type, label, url, description? }) — add a resource (type ∈ REPO|DOC|BRD|DESIGN|CLOUD|DASHBOARD|SOP|ENVIRONMENT|OTHER).
remove_project_resource({ projectId, resourceId }) — remove one.
Agile planning: sprints, story points, custom fields, workflows & analytics
create_task and update_task now also take storyPoints (integer 0–100), sprintId, and workflowStatusId (a custom board column — setting it also syncs the task's canonical status), so an agent can estimate, schedule, and move cards on a customized board.
- Sprints —
list_sprints({ projectId }) (with story-point rollups), create_sprint({ projectId, name, startsAt, endsAt, goal? }), update_sprint, close_sprint, and delete_sprint. Assign a task to a sprint with update_task({ sprintId }).
- Custom fields —
list_custom_fields({ projectId }) reveals each field's id, type, and SELECT options; create_custom_field({ projectId, name, type, options? }) defines one (type ∈ TEXT|NUMBER|SELECT|DATE). Set a task's values with set_task_fields({ taskId, values: [{ fieldId, value }] }) (pass null to clear).
- Custom workflow —
list_workflow_columns({ projectId }) lists the board columns (each column's id is the workflowStatusId to move a card to); create_workflow_column({ projectId, name, category, color?, isDefault? }) adds one.
- Flow analytics —
get_project_metrics({ projectId, from?, to? }) returns cycle/lead-time percentiles, weekly throughput, and a cumulative flow diagram (defaults to the last 90 days).
Discover valid values first: call list_custom_fields before set_task_fields, and list_workflow_columns before setting a workflowStatusId.
Work platform: initiatives, docs & time
The tools an agent needs to plan against the roadmap, pull context out of the wiki, and log its own time. update_task also takes initiativeId to file a task under a cross-project initiative.
- Initiatives (roadmap) —
list_initiatives({ teamId }) returns the team's initiatives with their linked project IDs and a task rollup; create_initiative({ teamId, name, status?, color?, startDate?, targetDate?, ownerId?, description? }) adds one (status ∈ PLANNED|ACTIVE|PAUSED|SHIPPED|CANCELLED). File a task under one with update_task({ initiativeId }) — the initiative must belong to the same team as the task's project.
- Docs / wiki —
list_docs({ teamId, projectId? }) returns the page tree (titles only; omit projectId for the team-level wiki); get_doc({ docId }) reads a page's full markdown body; create_doc({ teamId, title?, projectId?, parentId?, icon? }) creates an empty page; update_doc({ docId, content?, title?, icon?, archived? }) writes it (any title/content change snapshots the prior revision).
- Time —
log_time({ taskId, minutes, description? }) records a manual time entry against a task, which rolls up into the task's logged minutes and the owner's weekly timesheet.
Read before you write: list_docs to find a page ID, then get_doc for its content; list_initiatives to find an initiativeId before update_task.
Approvals & OKRs
Agent runs pause on approval gates; humans set the quarter's objectives — these tools let either side read and move both from any MCP client:
- Approvals (the decision inbox) —
list_approvals({ projectId?, status? }) lists approval requests on projects you can see (status ∈ PENDING|APPROVED|DENIED|EXPIRED|ALL, default PENDING); decide_approval({ approvalId, decision: "approve"|"deny", note? }) records the verdict. Exactly one decision wins across every surface (web, email link, Slack, MCP) — a second decision returns a 409 naming who decided first. On success the orchestrator forwards the verdict into the suspended run.
- OKRs —
list_objectives({ teamId, period? }) returns the team's objectives with key results and derived progress (0..1); update_key_result({ objectiveId, keyResultId, currentValue }) is the check-in that moves the number. Find IDs with list_objectives first.
Manual ↔ agent parity
The same board, two hands: everything a developer does at the terminal, an agent can do over MCP (and vice versa).
| Link a repo to its project | taskpod init / taskpod link <KEY> | init_workspace |
| Pull project context | taskpod sync / taskpod pull | sync_context |
| Share a learning | .taskpod/learnings.md + taskpod sync | record_learning |
| Pre-load a repo's knowledge | taskpod ingest (offered by init) | own repo access + create_doc / record_learning / create_task |
| Board overview | taskpod status | get_sprint_status |
| My tasks | taskpod mine | list_tasks (filtered) |
| Search existing knowledge | Taskpod web (top-nav search) | search_knowledge |
| Task detail | taskpod show <ticket> | get_task / resume_task |
| Start work | taskpod start <ticket> | checkpoint_task (→ IN_PROGRESS) |
| Finish work | taskpod done <ticket> | checkpoint_task (→ IN_REVIEW) |
| Typed comment | taskpod comment <ticket> -t … | add_comment |
| Set an ETA | taskpod eta <ticket> <when> | update_task (etaAt) |
| Reassign / hand off | taskpod assign / taskpod handoff | handoff_to_human / update_task |
| Project resources | taskpod resources / taskpod setup | list_project_resources / add_project_resource |
| Approvals inbox | Taskpod web / Slack buttons | list_approvals |
| Decide an approval | Taskpod web / email link / Slack | decide_approval |
| Read the OKRs | Taskpod web (OKR board) | list_objectives |
| Key-result check-in | Taskpod web (OKR board) | update_key_result |
| Connect AI tools | taskpod agent-setup (offered by init) | — (it's what wires the agent in) |
Development
npm install
npm run build
node dist/taskpod.js help
Publishing
Publishing is automated by GitHub Actions (.github/workflows/publish.yml): push a version tag and CI builds and publishes to npm.
npm version patch
git push --follow-tags
One-time setup: add an npm automation token as the NPM_TOKEN repository secret (GitHub → Settings → Secrets and variables → Actions).
License
MIT