Detailed instructions for installing, configuring, and integrating agent-tasks with any MCP client.
- Prerequisites
- Installation
- Client Setup
- Hooks
- Running as Standalone Server
- Configuration Options
- Database
- Troubleshooting
- Node.js >= 20.11 (for native ES module support and
node:built-in imports) - npm >= 10
node --version # v20.11.0 or later
npm --version # v10 or laternpm install -g agent-tasksgit clone https://github.com/keshrath/agent-tasks.git
cd agent-tasks
npm install
npm run buildThis compiles TypeScript to dist/ and copies UI files to dist/ui/.
node dist/server.jsOpen http://localhost:3422 — you should see the kanban dashboard with empty columns for each pipeline stage.
agent-tasks works with any MCP client (stdio) or HTTP client (REST API). Pick your client below.
From the agent-tasks clone:
node scripts/setup.jsThis detects Claude Code, registers the MCP server in ~/.claude.json, wires all 5 hooks into ~/.claude/settings.json, and grants mcp__agent-tasks__* permission in one shot. Restart Claude Code afterwards to pick up the new config.
Edit ~/.claude/settings.json:
{
"mcpServers": {
"agent-tasks": {
"command": "npx",
"args": ["agent-tasks"]
}
},
"permissions": {
"allow": ["mcp__agent-tasks__*"]
}
}Start a new Claude Code session. Try:
Create a task called "Test task" with priority 5
Claude should call task_create and confirm the task was created.
The dashboard auto-starts at http://localhost:3422.
opencode.json (project root) or ~/.config/opencode/opencode.json (global):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"agent-tasks": {
"type": "local",
"command": ["node", "/absolute/path/to/agent-tasks/dist/index.js"],
"environment": {
"AGENT_TASKS_PORT": "3422"
}
}
}
}.cursor/mcp.json in your project root:
{
"mcpServers": {
"agent-tasks": {
"command": "node",
"args": ["/absolute/path/to/agent-tasks/dist/index.js"],
"env": {
"AGENT_TASKS_PORT": "3422"
}
}
}
}~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"agent-tasks": {
"command": "node",
"args": ["/absolute/path/to/agent-tasks/dist/index.js"],
"env": {
"AGENT_TASKS_PORT": "3422"
}
}
}
}If your tool doesn't support MCP, use the REST API:
# Create a task
curl -X POST http://localhost:3422/api/tasks \
-H 'Content-Type: application/json' \
-d '{"title": "Fix login bug", "priority": 5, "project": "backend"}'
# List tasks
curl http://localhost:3422/api/tasks
# Advance a task
curl -X POST http://localhost:3422/api/tasks/1/advanceSee API.md for the full REST reference.
Hooks automate pipeline workflows — dashboard announcements, TodoWrite bridging, and task cleanup. Support varies by client.
agent-tasks ships 5 hook scripts. scripts/setup.js installs them automatically; the block below shows the manual equivalent for ~/.claude/settings.json:
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "node \"/path/to/agent-tasks/scripts/hooks/session-start.js\"",
"timeout": 5
},
{
"type": "command",
"command": "node \"/path/to/agent-tasks/scripts/hooks/task-cleanup-start.js\"",
"timeout": 10
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "node \"/path/to/agent-tasks/scripts/hooks/pipeline-enforcer.mjs\"",
"timeout": 10
}
]
}
],
"PreToolUse": [
{
"matcher": "TodoWrite",
"hooks": [
{
"type": "command",
"command": "node \"/path/to/agent-tasks/scripts/hooks/todowrite-bridge.mjs\"",
"timeout": 5
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "node \"/path/to/agent-tasks/scripts/hooks/task-cleanup-stop.js\"",
"timeout": 10
}
]
}
],
"SubagentStop": [
{
"hooks": [
{
"type": "command",
"command": "node \"/path/to/agent-tasks/scripts/hooks/task-cleanup-stop.js\"",
"timeout": 10
}
]
}
]
}
}Replace /path/to/agent-tasks with the actual path.
| Hook | Event | Purpose |
|---|---|---|
session-start.js |
SessionStart | Announces dashboard URL |
task-cleanup-start.js |
SessionStart | Auto-fails tasks from dead sessions |
pipeline-enforcer.mjs |
UserPromptSubmit | Requires an active pipeline task for real work |
todowrite-bridge.mjs |
PreToolUse (TodoWrite) | Syncs TodoWrite todos to pipeline |
task-cleanup-stop.js |
Stop + SubagentStop | Blocks stop, then auto-fails orphaned tasks |
See docs/hooks.md for the full hook reference including the work-prompt classifier, environment variables, and test coverage.
Sweeps for tasks assigned to sessions that are no longer online and auto-fails them. Runs on both Stop (main session) and SubagentStop (spawned agents), complementing the SessionStart sweep.
The hook does not block the stop. Claude Code's Stop event does not carry enough metadata to reliably identify which agent-comm session is stopping (multiple sessions share the same Claude install), so attributing "your" open tasks to the stopping session was error-prone — it frequently flagged sibling sessions' work. The hook now only cleans up tasks owned by agents whose agent-comm status is no longer online.
sequenceDiagram
participant CC as Claude Code
participant Hook as task-cleanup-stop.js
participant CommDB as agent-comm DB
participant TasksDB as agent-tasks DB
CC->>Hook: Stop event (stdin JSON)
Hook->>CommDB: SELECT name FROM agents WHERE status = 'online'
Hook->>TasksDB: SELECT open tasks WHERE assigned_to NOT IN onlineAgents
alt Has orphaned tasks
Hook->>TasksDB: UPDATE tasks SET status = 'failed'
Hook->>CC: {decision: "approve", reason: "Auto-failed N orphaned tasks"}
else No orphans
Hook->>CC: {} (allow stop)
end
Open tasks whose assigned agent is still online are left untouched — their session is assumed to be alive and actively working on them.
Catches tasks orphaned by sessions that crashed, were killed, or otherwise ended without the Stop hook firing.
On every session start:
- Finds all tasks assigned to sessions that are no longer online in the agent-comm DB
- Auto-fails them with reason
"Session no longer running (stale task cleanup on session start)" - Logs the cleanup to stderr
This is the safety net — even if the Stop hook never fires, the next session to start will clean up.
Intercepts Claude Code's built-in TodoWrite tool and syncs todos to agent-tasks. Every todo Claude creates automatically appears on the kanban board.
When Claude Code calls TodoWrite, the hook:
- Reads the tool input from stdin
- Extracts todos with
in_progressorpendingstatus - POSTs each as a new task to
http://localhost:3422/api/tasks - Maps priority:
high-> 10,medium-> 5,low-> 1 - Tags all synced tasks with project
claude-todos - Returns an empty JSON object to let the original tool proceed
sequenceDiagram
participant CC as Claude Code
participant Hook as todowrite-bridge.js
participant AT as agent-tasks
CC->>Hook: PreToolUse (TodoWrite, stdin JSON)
Hook->>Hook: Parse todos from tool_input
loop Each pending/in_progress todo
Hook->>AT: POST /api/tasks {title, priority, project}
AT-->>Hook: 201 Created
end
Hook->>CC: {} (let original tool proceed)
| Variable | Default | Description |
|---|---|---|
AGENT_TASKS_URL |
http://localhost:3422 |
agent-tasks REST API base URL |
The hook has a 3-second timeout per request. If agent-tasks is not running, it silently fails and lets TodoWrite proceed.
OpenCode supports lifecycle hooks via JavaScript/TypeScript plugins. Create a plugin in .opencode/plugins/ or ~/.config/opencode/plugins/:
// .opencode/plugins/agent-tasks.ts
import type { Plugin } from '@opencode-ai/plugin';
export const AgentTasksPlugin: Plugin = async ({ client }) => {
return {
event: async (event) => {
if (event.type === 'session.created') {
// Equivalent to SessionStart — agent sees pipeline instructions via AGENTS.md
}
if (event.type === 'tool.execute.before') {
// Equivalent to PreToolUse — could intercept todo creation
}
},
};
};Available events: session.created, session.idle, tool.execute.before, tool.execute.after, message.updated, file.edited.
Combine with AGENTS.md instructions (see below).
Cursor and Windsurf don't support lifecycle hooks. Use the client's system prompt / instructions file (see Agent Rules below).
The TodoWrite bridge is Claude Code-specific. Other clients should use task_create directly.
Hooks enforce task cleanup and TodoWrite bridging, but every platform needs written instructions telling the agent how to use the pipeline. Without rules, agents create tasks but skip stages or forget to advance.
Add the appropriate block to your platform's instructions file:
| Platform | File |
|---|---|
| Claude Code | CLAUDE.md (project root or ~/.claude/CLAUDE.md) |
| OpenCode | AGENTS.md (project root) |
| Cursor | .cursorrules (project root) |
| Windsurf | .windsurfrules (project root) |
## Dev Pipeline
All work flows through a shared pipeline. Dashboard: http://localhost:3422
Pipeline stages: **backlog → spec → plan → implement → test → review → done**
### How to use
1. **Check for work first** — call `task_list` to see what's in flight
2. **Create tasks** — `task_create` with title, description, priority, project
3. **Claim it** — `task_stage` with `action: "claim"` assigns it to your session and advances from backlog
4. **Do the work** — advance through stages with `task_stage` (`action: "advance"`)
5. **Attach artifacts** — at each stage, use `task_artifact` (specs, plans, code summaries, test results)
6. **Complete** — `task_stage` with `action: "complete"` when done, or `action: "fail"` if abandoned
### Rules
- **Never work without a task** — if there isn't one, create it
- **Never skip stages** — move through spec → plan → implement → test → review
- **Attach artifacts at each stage** — the pipeline is only useful if it shows what was decided/built/tested
- **Always complete or fail your tasks before stopping**
- Break large work into sub-tasks with `task_create` (`parent_id`) or dependencies via `task_update` (`dependency` field)
### Communicate around tasks (requires agent-comm)
If agent-comm is available, coordinate task work with other agents:
- **Claiming a task** — post to "general": "Claiming task #42: implement auth module"
- **Advancing a stage** — post to "general": "Task #42 moved to test — all unit tests passing"
- **Blocked on a dependency** — post to "general": "Blocked on task #38, need the DB schema first"
- **Editing shared files** — use `comm_state_set("locks", "path/to/file", "my-name")` before editing, `comm_state_delete` when done
- **Finishing work** — post a summary to "general" before stopping
See the [agent-comm SETUP guide](https://github.com/keshrath/agent-comm/blob/main/docs/SETUP.md) for full communication instructions.Without these rules, agents typically:
- Create a task and jump straight to "done" (skipping stages)
- Never attach artifacts (the pipeline shows nothing useful)
- Forget to complete/fail tasks when stopping (leaves orphans)
- Work on the same files as other agents without coordinating (merge conflicts)
Hooks help enforce cleanup in Claude Code, but the written rules drive the actual workflow discipline.
# Default port (3422)
npm run start:server
# Custom port
npm run start:server -- --port 8080
# Or directly
node dist/server.js --port 8080Useful for viewing the dashboard while MCP servers run in separate terminals, or integrating via REST API.
| Variable | Default | Description |
|---|---|---|
AGENT_TASKS_DB |
~/.agent-tasks/agent-tasks.db |
Path to the SQLite database file |
AGENT_TASKS_PORT |
3422 |
HTTP/WebSocket port for the dashboard |
AGENT_TASKS_INSTRUCTIONS |
enabled | Set to 0 to disable embedded instructions in MCP tool responses |
AGENT_COMM_URL |
http://localhost:3421 |
Agent-comm REST API URL (for bridge notifications and heartbeat cleanup) |
agent-tasks integrates with agent-comm for two features:
- Bridge notifications — when tasks are claimed, advanced, or commented on, agent-tasks sends messages to affected agents via agent-comm
- Heartbeat-based cleanup — agent-tasks queries agent-comm's
GET /api/agentsendpoint to check agent liveness, and auto-fails tasks assigned to dead agents
To enable:
- Install and start agent-comm (default port: 3421)
- Set
AGENT_COMM_URLif using a non-default URL - agent-tasks checks heartbeats on startup (10s delay) and when
task_cleanupis called withmode: "stale_agents"ormode: "all"
If agent-comm is not running, both features degrade gracefully — notifications are silently dropped and stale agent detection is skipped.
The default pipeline is: backlog > spec > plan > implement > test > review > done
You can customize stages per project using the task_pipeline_config MCP tool:
Use task_pipeline_config to set stages for project "my-project" to: ["todo", "doing", "testing", "done"]
Or via REST:
# Get current pipeline config
curl http://localhost:3422/api/pipeline
# Get pipeline for a specific project
curl http://localhost:3422/api/pipeline?project=my-projectGate guards enforce quality requirements before tasks can advance to the next stage. Configure via task_pipeline_config:
Use task_pipeline_config to set gate_config for project "backend" with gates:
- implement stage requires artifact named "code-summary"
- test stage requires artifact named "test-results" and a comment
- review stage requires approval
This translates to:
{
"gate_config": {
"gates": {
"implement": {
"require_artifacts": ["code-summary"],
"require_min_artifacts": 1
},
"test": {
"require_artifacts": ["test-results"],
"require_comment": true
},
"review": {
"require_approval": true
}
}
}
}| Gate option | Type | Description |
|---|---|---|
require_artifacts |
string[] |
Named artifacts that must exist at the current stage |
require_min_artifacts |
number |
Minimum number of artifacts at the current stage |
require_comment |
boolean |
At least one comment must exist on the task |
require_approval |
boolean |
An approved approval must exist for the current stage |
If a gate check fails, task_stage (with action: "advance") returns an error explaining what's missing.
By default, the database is stored at ~/.agent-tasks/agent-tasks.db. Override with AGENT_TASKS_DB.
cp ~/.agent-tasks/agent-tasks.db ~/.agent-tasks/agent-tasks.db.bakrm ~/.agent-tasks/agent-tasks.dbA new database will be created automatically on the next start.
The database uses schema versioning (currently V4) with automatic migrations. Migrations are idempotent.
- Verify the server is running:
curl http://localhost:3422/health - Check the port isn't in use:
lsof -i :3422(macOS/Linux) ornetstat -ano | findstr 3422(Windows) - Try a different port:
AGENT_TASKS_PORT=8080 npm run start:server
- Verify the path in your config is absolute and points to
dist/index.js - Ensure you ran
npm run buildafter cloning - Restart your client after changing config
- The WebSocket server polls SQLite every 2 seconds to detect cross-process changes
- Ensure all MCP instances use the same database file (
AGENT_TASKS_DB)
- Verify the hook script path is absolute in
settings.json - Check that the agent-tasks server is running (the bridge POSTs to the REST API)
- Check stderr for errors: the bridge logs to stderr with
[todowrite-bridge]prefix
- Both cleanup hooks require
better-sqlite3(included in agent-tasks dependencies — runnpm installin the agent-tasks directory) - The stop hook identifies sessions via the agent-comm DB — ensure your session calls
comm_registeron startup - Check stderr for
[task-cleanup-start]messages on session start - The counter file at
~/.claude/task-cleanup-counter.jsoncan be deleted to reset block state
| Feature | Claude Code | OpenCode | Cursor | Windsurf |
|---|---|---|---|---|
| MCP stdio transport | Yes | Yes | Yes | Yes |
| Lifecycle hooks | Yes (JSON) | Yes (plugins) | No | No |
| TodoWrite bridge | Yes | No | No | No |
| System prompt file | CLAUDE.md | AGENTS.md | .cursorrules | .windsurfrules |
| REST API fallback | Yes | Yes | Yes | Yes |