mcp-task-fractionator
Tools at a glance
Section titled “Tools at a glance”| Tool | What it takes | What it returns | Why your brain cares |
|---|---|---|---|
decompose | { goal, time_budget? } | 3–12 atomic tasks with acceptance criteria and a one-paragraph rationale | converts the wall of “plan the migration” into things small enough that starting one is cheaper than avoiding it |
next_one | { project } | exactly one task, plus reasoning and a confidence number | answers “what do I do right now” without re-deciding priorities — the choice fatigue moves out of your head and into the server |
Before / after
Section titled “Before / after”The fractionator’s whole job is the column-shift below: vague intent on the left, atomic moves on the right.
| Before — vague goal | After — atomic tasks (with time budgets) |
|---|---|
| “Plan the migration.” | 1. Inventory current staging DB schemas (PT20M) — acceptance: list of every table + row-count in a markdown file. |
| 2. Read the prod runbook end-to-end once (PT30M) — acceptance: bullet-list of every step that touches a write path. | |
| 3. Draft the migration playbook headers only (PT15M) — acceptance: section titles, no body text. | |
| 4. Identify the three riskiest steps (PT25M) — acceptance: each step has one rollback line. | |
| 5. Sketch the rollback plan for step 1 only (PT30M) — acceptance: a checklist Sarah could follow if I were offline. |
The rationale paragraph that ships with the response surfaces every assumption (timezone, what “end of week” meant, what was deliberately dropped) so the user can correct any one of them without re-running the decomposition.
Server card
Section titled “Server card”mcp-task-fractionator carves a vague goal into a small ordered list of atomic 5–90 minute tasks with explicit acceptance criteria and dependency edges. It is stateless — persistence is the caller’s job, via mcp-cognitive-graph.
- Package:
packages/mcp-task-fractionator/ - Version:
0.0.3 - Schemas:
packages/mcp-task-fractionator/schemas/*.schema.json - ADR: 0003 — Task fractionator tool design
- Schema
$idprefix:https://schemas.neurodock.org/mcp-task-fractionator/v0.1.0/
Tools (detailed contract)
Section titled “Tools (detailed contract)”| Tool | Input | Output |
|---|---|---|
decompose | { goal: string, time_budget?: string, max_chunk_size?: integer, time_buffer_multiplier?: number, motor_fatigue_aware?: boolean } | { tasks: Task[], rationale: string, time_buffer_multiplier?, motor_fatigue_aware?, truncated? } |
next_one | { project: string } | { task: Task, reasoning: string, confidence: number } |
decompose
Section titled “decompose”Input:
goal— plain-language goal, 5–500 characters. Treated as private user data; never logged.time_budget— optional ISO 8601 duration (PT4H,P3D,PT30M). The totalestimated_minutesacross returned tasks fits within the budget; otherwise the server returnsBUDGET_INFEASIBLErather than silently truncating.
Optional neurotype knobs (ADR 0011 — additive, default to today’s behaviour when absent; the server never branches on a neurotype enum):
max_chunk_size— integer1–20. Caps the number of tasks returned, below the normal 3–12 target. When the goal naturally needs more steps, the server keeps the lowest-sequenceprefix (a valid sub-DAG with no dangling dependencies), setstruncated: true, and says so in the rationale. It never silently drops steps or returns an invalid order.time_buffer_multiplier— number1.0–3.0. When greater than 1.0, each task gains an additivepadded_minutesequal toround(estimated_minutes × multiplier);estimated_minutesstays raw so a presentation layer never double-pads. A value of1.0(or omitting the field) produces no padding. Out-of-range values are rejected withINPUT_INVALID.motor_fatigue_aware— boolean. When true, the server echoes the preference and names it in the rationale so the client/skill can pace breaks. The server has no view of keystroke/click activity and does not infer fatigue.
Output:
tasks— array of 1–20 tasks (target 3–12, per ADR 0003). Each task has:id— UUIDv4, server-generated.title,description— verb-led, concrete.estimated_minutes— integer in[5, 90]. Floor prevents trivial-shred; ceiling enforces atomicity. Always raw — never buffer-adjusted.padded_minutes— optional, additive. Present only whentime_buffer_multipliergreater than 1.0 was supplied; equalsround(estimated_minutes × multiplier). Omitted otherwise.acceptance_criteria— non-empty array. Required. An empty array is rejected asACCEPTANCE_CRITERIA_REQUIRED.dependencies— UUIDv4 references to siblings in the same response. Cycles are rejected.sequence— 1-indexed total order. Distinct for every task;next_oneis “sequence = 1 of the unfinished subset”.tags— free-form labels for filtering.
rationale— one paragraph the user can read in 5 seconds. Surfaces assumptions (“I assumed Friday meant end-of-business Friday in your local timezone”). Not a marketing summary. Names any active knob (the padding multiplier, truncation, motor-fatigue-aware preference).time_buffer_multiplier,motor_fatigue_aware,truncated— optional, additive echoes. Each is present only when the corresponding knob was active; omitted otherwise so a no-knob call is byte-identical to the pre-R2 wire shape.
next_one
Section titled “next_one”Reads from mcp-cognitive-graph to find pending tasks under the named project. Returns exactly one task plus reasoning and a confidence number.
The fractionator owns the decomposition algorithm; the graph owns the state.
Error codes
Section titled “Error codes”| Code | Meaning |
|---|---|
GOAL_REQUIRED | Goal missing or shorter than 5 characters after trimming. |
GOAL_TOO_LONG | Goal exceeded 500 characters. Split the goal itself. |
TIME_BUDGET_UNPARSEABLE | Budget did not match the ISO 8601 duration regex. No silent fallback. |
INPUT_INVALID | An R2 neurotype knob was out of range: max_chunk_size not a positive integer 1–20, or time_buffer_multiplier outside [1.0, 3.0]. Rejected, never clamped. |
BUDGET_INFEASIBLE | No task list fits the budget while still covering the goal. May include minimum_feasible_minutes. |
DEPENDENCY_CYCLE | Candidate decomposition produced a cycle. Server bug, surfaced explicitly. |
ACCEPTANCE_CRITERIA_REQUIRED | Internal invariant — a candidate task had zero acceptance criteria. |
DECOMPOSITION_UNAVAILABLE | Local heuristic engine could not produce a credible decomposition. Payload SHOULD include a clarifying_question string. |
Statelessness
Section titled “Statelessness”decompose returns a task list but does NOT persist it. Callers (typically skills) write the tasks to mcp-cognitive-graph:
- Each task becomes an entity (
record_factwith the task id as subject andestimated_minutes,acceptance_criteriaas facts). - Each dependency becomes a fact with
predicate: "depends_on". - The project becomes an entity that owns the tasks via
predicate: "part_of"(note:part_oflands in v0.2; v0.1 usesbelongs_to).
The skill SDK ships a one-liner — decompose_and_persist(goal, project, time_budget?) — for the common path.
Privacy
Section titled “Privacy”- No remote calls.
- No LLM call from inside the server. The v0.2
decompose_with_assistpath will accept an LLM-drafted decomposition as input; the server remains the schema and invariants authority. - Goal text is never logged — not at info, not at debug, not in error payloads. Validation errors reference field names, not content.
Versioning
Section titled “Versioning”- Additive-only within
v0.1.x. - The 5–90 minute
estimated_minutesrange, the 1–20 task count range, and the required non-emptyacceptance_criteriaare part of the contract; changing them is a major bump.
What’s next
Section titled “What’s next”- ADR 0003 for the full design rationale.
mcp-cognitive-graph— the state owner.