Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Tools

The mcp-plan server exposes the following tools over MCP. All results are returned as structured JSON content. Task ids are UUIDs generated by the server.

Returns the full task object, found by either its id or its unique link. Exactly one of id or link must be provided (XOR); passing both or neither is rejected.

task({ id?: string, link?: string })
{
  "id": "…",
  "parent_id": null,
  "source_id": "gh",
  "link": "https://example.com/task-42",
  "title": "Research the API",
  "description": "Read .md docs, list endpoints",
  "status": "ready",
  "priority": "medium",
  "retries": 0,
  "created_at": "…",
  "updated_at": "…",
  "estimated_tokens_in": 4000,
  "estimated_tokens_reasoning": 2000,
  "estimated_tokens_out": 800
}

Fields: id, parent_id, source_id, link, title, description, status, priority, retries, created_at, updated_at, estimated_tokens_in, estimated_tokens_reasoning, estimated_tokens_out.

  • status: ready | success | failure | escalated
  • priority: critical | high | medium | low

sources() — list all sources

Returns every configured source, ordered by id.

sources()
[
  {
    "id": "gh",
    "title": "GitHub issues",
    "description": "fetch instructions",
    "type": "poll"
  }
]

source(id) — fetch a single source

Returns an individual source by its id. Returns an error if no source with that id exists.

source({ id: string })
{
  "id": "gh",
  "title": "GitHub issues",
  "description": "fetch instructions",
  "type": "poll"
}

children(parent_id?) — list children of a task

Returns a compact array of direct children. When parent_id is omitted (or null), returns root-level tasks.

children({ parent_id?: string })
[
  {
    "id": "…",
    "title": "Outline the design doc",
    "status": "ready",
    "priority": "high",
    "estimated_tokens_in": 1200,
    "estimated_tokens_reasoning": 600,
    "estimated_tokens_out": 400
  }
]

insert(...) — create a task

Inserts a new task with status='ready' and returns its id.

insert({
  title: string,
  description: string,
  source_id: string,
  parent_id?: string,
  priority?: "critical" | "high" | "medium" | "low",
  link?: string,
  estimated_tokens_in: integer,
  estimated_tokens_reasoning: integer,
  estimated_tokens_out: integer
})

title, description, source_id and the three estimated_tokens_* fields are required. priority defaults to medium; parent_id and link are optional. link is unique when set, so inserting a task that shares an existing link is rejected by the database. A parent_id that does not exist is rejected as well.

{ "id": "…" }

complete(task_id, status) — mark success or failure

Sets status to success or failure. Returns the updated task. Any other value is rejected.

complete({ task_id: string, status: "success" | "failure" })

fail(task_id, status) — record a failure

Increments retries and sets status to failure; status here is the failure reason and is recorded in the logs. The task is escalated instead once retries reaches the configured max_retries. Returns the updated task.

fail({ task_id: string, status: string })

escalate(task_id) — block for human review

Marks the task as escalated. Escalated tasks are excluded from queue() until a human clears them (via ready).

escalate({ task_id: string })

ready(id, ...) — update and requeue

Updates mutable fields and sets status back to ready. Returns the updated task. Every field except id is optional and only those provided are updated.

ready({
  id: string,
  title?: string,
  description?: string,
  priority?: "critical" | "high" | "medium" | "low",
  link?: string,
  estimated_tokens_in?: integer,
  estimated_tokens_reasoning?: integer,
  estimated_tokens_out?: integer
})

queue() — tasks needing work

Returns tasks requiring attention, sorted by priority (critical > high > medium > low) and then by workload type (planning before execution), bounded by the configured queue_limit.

Excludes success and escalated tasks. Failed tasks whose retries reach max_retries are automatically escalated and omitted.

queue()
[
  {
    "id": "…",
    "parent_id": null,
    "source_id": "gh",
    "link": null,
    "title": "…",
    "description": "…",
    "status": "ready",
    "priority": "critical",
    "retries": 0,
    "created_at": "…",
    "updated_at": "…",
    "estimated_tokens_in": 0,
    "estimated_tokens_reasoning": 0,
    "estimated_tokens_out": 0,
    "kind": "planning",
    "duration_secs": 852
  }
]

The kind (planning | execution) is decided by the server:

duration_secs = estimated_tokens_in / tps_in
  + (estimated_tokens_reasoning + estimated_tokens_out) / tps_out

When duration_secs > max_task_duration_secs the task is planning, otherwise execution. The agent only ever estimates tokens; classification is enforced by the server.