create_task
Create a new project task with details like title, dates, priority, assignee, and GitHub issue/PR links, then return its ID for tracking and follow-up updates.
Instructions
Create a new task in a project. Returns the created task with its ID.
Tool call template
Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {
"project_id": "<project_id>",
"title": "<title>"
},
"name": "create_task"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | Title of the task | |
| due_date | No | Date the task is due, as YYYY-MM-DD. | |
| priority | No | Priority level (0-5, higher is more important) | |
| project_id | Yes | The ID of the project to add the task to | |
| sort_order | No | Position among the project's tasks (lower sorts first). NOT wired on the REST create path — POST /api/projects/:id/tasks always assigns MAX(sort_order)+1 and ignores this field on create. Set it after creation with update_task instead. | |
| start_date | No | Date work is planned to start, as YYYY-MM-DD. | |
| description | No | Detailed description of the task | |
| is_milestone | No | Mark this task as a milestone, drawn differently on the Gantt view. NOT wired on the REST create path — POST /api/projects/:id/tasks does not accept this field; the column is left at its default (0). Set it after creation with update_task instead. | |
| github_pr_url | No | URL of the GitHub Pull Request implementing this task. Used to fetch the PR diff for AI verification and to match incoming CI status (check_run/check_suite/workflow_run webhooks) back to this task. | |
| parent_task_id | No | Make this a SUBTASK of the given task. The parent must be in the same project, and a subtask cannot itself have subtasks (one level only). A parent with subtasks takes its status from them: any subtask in progress makes the parent in progress, and all subtasks done makes it ready to complete. AND IT HOLDS THE PARENT OPEN (GH #387): while this subtask is not done, marking the parent done is REFUSED with 403 OPEN_SUBTASKS — the roll-up used to be display-only and now has teeth. That is the point of filing an adjacent finding as a subtask rather than as a separate task. Re-parenting an existing task is update_task's parent_task_id. | |
| github_issue_id | No | The GitHub issue number this task tracks, set at creation. LOAD-BEARING, not bookkeeping: session_heartbeats.task_id is NOT NULL and the heartbeat endpoint resolves a session's GitHub issue number to a task through tasks.github_issue_id — a task created for an issue without this set emits heartbeats that have nowhere to land and is invisible on the live agent board. To change or clear it on an EXISTING task, use update_task's github_issue_id (which also accepts null, to unlink). | |
| assignee_user_id | No | User ID to assign the task to. Must be a member of the same account. Omit to leave the task unassigned. For a SECOND (or third, ...) assignee, do not call this again — use add_assignee after creation, since this field only ever sets a single owner at create time. | |
| github_issue_url | No | Full URL of the GitHub issue this task tracks, set at creation. Set it alongside github_issue_id so the two cannot disagree. | |
| estimated_minutes | No | Estimated time to complete in minutes | |
| verification_mode | No | Gate this task's own completion. "manual" (default) allows a plain status change to done. "ai_review" or "all" BLOCK marking the task done (403 VERIFICATION_REQUIRED) until ai_completion_score reaches 0.8 — run "Verify with AI" first. "ci_required" or "all" BLOCK it until a PR is linked (github_pr_url) with passing CI. Setting this arms a real check against your own future attempt to close the task. | |
| required_ci_checks | No | Which named CI checks (matched case-insensitively as a substring of the check name) must pass for "ci_required"/"all" verification_mode to consider CI satisfied — e.g. ["build","test"]. Read by GET /api/tasks/:id/ci-status's resolveRequiredChecks (app/functions/api/tasks/[id]/ci-status.js:13-32), NOT by the GitHub webhook handler, which sets ci_status unconditionally from whichever single check/workflow event just arrived. Omit to leave unset (falls back to the project's own required_ci_checks, then to requiring every check). NOT wired on the REST create path — POST /api/projects/:id/tasks does not accept this field. Set it after creation with update_task instead. | |
| acceptance_criteria | No | Criteria for task completion |