Zum Inhalt springen

MCP-Tools

96 tools at /api/mcp, grouped by the permission that gates them

This list is fetched from Motir when the page is requested, so it is whatever the server ships right now. Each tool shows the arguments it takes — their names, their types and which are required — read from the same registry that answers a tools/list handshake against /api/mcp, which is still the authoritative surface and carries each tool's full description. Which of these a given token may call depends on the grant it carries, so the list your client shows is already scoped to you.

Jedes Tool gibt an, was es mit Ihren Daten tut: Lesezugriffe ändert nichts, Schreibzugriffe fügt nur hinzu, und Destruktiv kann Vorhandenes ändern oder entfernen. Claude liest diese Hinweise und fragt nach, bevor es ein Tool verwendet, das nicht nur liest – es sei denn, Sie haben es erlaubt.

Argument tables render one level: a nested object or a list shows its type, and the handshake carries the shape inside it.

View project

Open the project and read its work items, boards, backlog and reports. · granted by default

  • dispatch_promptDispatch promptLesezugriffe

    The server-generated coding-agent prompt for one item — the same text the CLI hands an agent.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    sessionBranch
    optional
    stringOptional session branch to FALL BACK to when this item carries no lineage of its own — the unattended-run seed (`motir auto`). It never overrides: an item whose dependencies are already integrated, or that is itself integrated, keeps that branch, so a caller cannot redirect a live lineage.
    findingsPolicy
    optional
    stringOptional comma-separated list of the capabilities this run switches OFF for the agent — one or more of: log-bug, replan. Omitted renders the COMPLETE outcome protocol, which is what every caller wanting to read the real contract should do. An unrecognised capability is refused, never ignored.
    continueFrom
    optional
    stringOptional id of a DEAD dispatch run this prompt continues — the `deadRun.id` `claim_work_item_continue` returned. The prompt then says how that run ended and where its work stands. A run that is unknown, still running or succeeded is refused with CONTINUE_FROM_INVALID, never ignored.
  • get_approval_gateGet approval gateLesezugriffe

    The decision a person made on one approval gate — the note they wrote when they sent your work back, who wrote it, when, and on which version.

    PropertyTypeDescription
    key
    required
    stringThe work item the gate hangs off — the project key, a dash, the number (e.g. "ACME-7"), case-insensitive. The card whose approval you are asking about, not the gate id (gates have no public ids to address).
    kind
    required
    string
    decision_approval · design_result · acceptance_result · pull_request_approval · decision_choice · decision_confirmation · plan_approval · pull_request_merge · manual_work
    Which decision to read. `decision_approval` is the gate on a `type: decision` card you authored; `design_result` the one your published design raised; `acceptance_result` a story run’s receipt; `pull_request_approval` the approve-and-merge question over a run’s whole delivery set; `decision_choice` and `decision_confirmation` the two decision kinds a person answers directly. `plan_approval` belongs to a PLAN rather than to a card, so no card has one. `pull_request_merge` is built and withdrawn — only historical rows exist. `manual_work` is a manual card a run reached, waiting on a person to do the work and mark it done.
  • get_designGet designLesezugriffe

    The APPROVED design of one design card, with short-lived links to its files — or which of five reasons there is none.

    PropertyTypeDescription
    key
    required
    stringThe DESIGN CARD's identifier — the project key, a dash, the number (e.g. "ACME-7"), case-insensitive. Not the key of the card that waits on the design: for that, call `list_designs` with `blockersOf`.
  • get_planRead plan proposalsLesezugriffe

    A plan with the proposals it bundles: what the planner actually proposed, not just how much — including a proposed obsolescence mark (current → proposed, with its note) and its supersedes edges, named by key.

    PropertyTypeDescription
    planId
    required
    stringThe plan id — as returned by an `expand_item` submit, by `get_plan_status`, or shown on the plan in Motir.
  • get_plan_statusPlan statusLesezugriffe

    What became of a submitted planning job — its state, and how many proposals it produced.

    PropertyTypeDescription
    planId
    optional
    stringThe plan id an `expand_item` submit returned. Pass this OR `jobId`.
    jobId
    optional
    stringThe job id an `expand_item` submit returned. Pass this OR `planId`.
  • get_project_stateGet project stateLesezugriffe

    A project's planning preconditions — established, code connected, indexed, repo set — before you plan.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the sprint belongs to — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value.
  • get_work_itemGet work itemLesezugriffe

    One item in full — description, status, parent or folder, children, dependency edges, a readiness verdict, the errors linked to it, and the latest refusal sent back on it.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"), case-insensitive. With `planId`, this may instead be a `planItem:<id>` temp-ref naming an `add` in that plan (case-SENSITIVE, as `add_plan_items` returned it).
    planId
    optional
    stringOPTIONAL — the id of a plan (as returned by `create_plan`) to PROJECT over. When given, the answer is computed over the project’s live tree ⊕ that plan’s proposals, so an agent can check the tree it is proposing BEFORE anyone reviews it. Omit it for the committed tree — a call without this argument behaves exactly as it did before projection existed. Nothing is created, mutated or persisted either way, and a proposal never becomes a work item except by approving the plan in Motir.
  • get_work_item_activityGet work item activityLesezugriffe

    One page of an item's discussion and change trail: comment threads and history, interleaved.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    view
    optional
    string
    all · comments · history
    Which stream to read: "all" (default) — comments and history interleaved in timestamp order; "comments" — comment threads with their replies; "history" — the change trail only.
    cursor
    optional
    stringOpaque continuation token from a previous call's nextCursor. Echo it back verbatim; never construct or parse one.
    order
    optional
    string
    asc · desc
    Page-walk direction. Omit for each view's shipped default ("desc" — newest first — for "all" and "history"; "asc" for "comments", the Jira default sort).
  • list_designsList designsLesezugriffe

    What a card is meant to be built against (`blockersOf`), or a page of the project’s approved designs. No links — take those from `get_design`.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value. Case-insensitive.
    blockersOf
    optional
    stringA work item key (e.g. "ACME-7"). When given, the answer is ONE VERDICT PER DESIGN CARD that work item is `blocked_by` — the designs it is supposed to be built against — instead of a page of the project’s designs. The other filters do not apply.
    pathPrefix
    optional
    stringReturn only designs holding a file whose repository path starts with this prefix — how a delta mock’s amended BASE is found (e.g. `design/work-items/`). Ignored with `blockersOf`. ⚠️ A filtered page can be SHORT — even empty — while more pages remain: keep paging until `nextCursor` is null before concluding nothing matches.
    query
    optional
    stringA case-insensitive substring of the design card’s TITLE. Ignored with `blockersOf`.
    cursor
    optional
    stringOpaque page cursor from a previous call’s `nextCursor`. Ignored with `blockersOf`. A SHORT page with a non-null cursor is normal when `pathPrefix` or `query` is set, so keep paging until it is null.
    limit
    optional
    integerPage size (1–100, default 25). Ignored with `blockersOf`.
  • list_foldersList foldersLesezugriffe

    Every folder of a project in one read — each folder's id and its path — to find a folder by name.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the folders belong to (e.g. "ACME").
  • list_projectsList projectsLesezugriffe

    Every project this token can reach, each with the projectKey every other tool takes.

    Takes no arguments.

  • list_readyList ready work itemsLesezugriffe

    One ready LANE of a project, paginated — leaves (default, never a bug, each naming its container), runnable containers, or bugs — in the order the Ready view shows.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value. Case-insensitive.
    lane
    optional
    string
    leaf · container · bug
    Which ready lane: "leaf" (default) — ready leaves that are not bug work, each naming its runnable container; "container" — runnable containers (a story, task or bug whose children are all leaves) holding a ready leaf, i.e. what a parent run takes; "bug" — a ready bug or a ready subtask of one. Rows come grouped by container, a group ranked by its best member.
    kinds
    optional
    string[]Restrict to these work item kinds; omit for any.
    priority
    optional
    string[]Restrict to these priorities; omit for any.
    assigneeId
    optional
    stringnullA user id to filter by; null or "unassigned" for the unassigned bucket; omit for any.
    cursor
    optional
    stringOpaque page cursor from a previous call’s nextCursor.
    limit
    optional
    integerPage size (1–200, default 50).
  • list_sprintsList sprintsLesezugriffe

    A project's sprints with state, goal, window and issue count, and the ids the sprint tools take.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the sprint belongs to — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value.
  • list_work_item_todosList a work item’s to-do listLesezugriffe

    Read a work item’s to-do list: its steps in order, which are done, and the progress.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
  • next_readyNext ready work itemLesezugriffe

    The next item of one ready lane — a leaf (default, never a bug) or a bug as a full dispatch payload, or the next runnable container for a parent run. The “what do I do next” call.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value. Case-insensitive.
    lane
    optional
    string
    leaf · container · bug
    Which ready lane: "leaf" (default) — ready leaves that are not bug work, each naming its runnable container; "container" — runnable containers (a story, task or bug whose children are all leaves) holding a ready leaf, i.e. what a parent run takes; "bug" — a ready bug or a ready subtask of one. Rows come grouped by container, a group ranked by its best member.
    kinds
    optional
    string[]Restrict to these work item kinds; omit for any.
    priority
    optional
    string[]Restrict to these priorities; omit for any.
    assigneeId
    optional
    stringnullA user id to filter by; null or "unassigned" for the unassigned bucket; omit for any.
    excludeIds
    optional
    string[]Work item ids already dispatched this loop — skip them.
  • search_work_itemsSearch work itemsLesezugriffe

    Search a project's items with the same filter grammar the advanced filter builder writes.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value.
    filter
    optional
    objectA versioned FilterAST envelope — the SAME shape the /items ?filter= URL and saved filters carry. Omit to search the whole project.
    cursor
    optional
    stringOpaque page cursor from a previous call’s nextCursor.
    limit
    optional
    integerPage size (1–50, default 50; the List’s server cap).
    planId
    optional
    stringOPTIONAL — the id of a plan (as returned by `create_plan`) to PROJECT over. When given, the answer is computed over the project’s live tree ⊕ that plan’s proposals, so an agent can check the tree it is proposing BEFORE anyone reviews it. Omit it for the committed tree — a call without this argument behaves exactly as it did before projection existed. Nothing is created, mutated or persisted either way, and a proposal never becomes a work item except by approving the plan in Motir.
  • search_work_items_semanticSearch work items by meaningDestruktiv

    Has this already been built? Search by MEANING rather than substring — keys, titles and scores only.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the sprint belongs to — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value.
    query
    required
    stringWhat you are looking for, in your own words — a phrase or a sentence, NOT a keyword. Motir embeds it for you: there is no model to pick and no vector to supply. Describe the CAPABILITY ("cards remember which columns are collapsed"), not a term you hope somebody used.
    limit
    optional
    integerCandidates to return; 1–50, default 10.
    minScore
    optional
    numberOptional cosine-similarity floor in [-1, 1]. NO default, deliberately (ADR Amendment 1): a spurious candidate costs one keyed read, a suppressed one costs a duplicate branch of the plan. Filter here only when you know what you asked.
  • skeletonProject skeletonLesezugriffe

    The whole project's tree shape in one read — every item's key, kind, title, status, parent, folder and obsolescence mark, with no paging loop.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the sprint belongs to — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value.
    limit
    optional
    integerMaximum rows to return; default (and maximum) 5000 — the whole tree. Pass a smaller number for a cheap peek. The response always reports `total`, `returned` and `truncated`, so a bounded answer is never mistaken for a whole one.
  • validate_planValidate a plan before anybody reviews itLesezugriffe

    Would approve TAKE this plan, is it finishable, is every edge on one level, and do its cross-parent edges have their parent edges? All four, before `final: true` — nobody else will ask.

    PropertyTypeDescription
    planId
    required
    stringThe plan id `create_plan` returned (or the id shown on the plan in Motir).
    condition
    optional
    string
    loose · tight
    How strict to be about a DONE gating item that sits OUTSIDE the set (sprint / subtree). `loose` (default): a done item outside the set counts as satisfied. `tight`: only an in-set item satisfies — a done item outside the set is reported as a blocker.
  • validate_sprintValidate sprint finishabilityLesezugriffe

    Is this sprint finishable? Names every in-sprint item still gated by work outside it.

    PropertyTypeDescription
    projectKey
    optional
    stringThe project key the sprint belongs to — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value. REQUIRED unless `planId` is given, which names its own project.
    sprintId
    optional
    stringThe sprint to validate; omit to validate the project’s ACTIVE sprint. Not accepted with `planId` — a projected verdict is always about the ACTIVE sprint.
    condition
    optional
    string
    loose · tight
    How strict to be about a DONE gating item that sits OUTSIDE the set (sprint / subtree). `loose` (default): a done item outside the set counts as satisfied. `tight`: only an in-set item satisfies — a done item outside the set is reported as a blocker.
    planId
    optional
    stringOPTIONAL — the id of a plan (as returned by `create_plan`) to PROJECT over. When given, the answer is computed over the project’s live tree ⊕ that plan’s proposals, so an agent can check the tree it is proposing BEFORE anyone reviews it. Omit it for the committed tree — a call without this argument behaves exactly as it did before projection existed. Nothing is created, mutated or persisted either way, and a proposal never becomes a work item except by approving the plan in Motir.
  • validate_work_itemValidate work-item finishabilityLesezugriffe

    Is this epic, story, task or bug finishable, is every edge on one level, and do its cross-parent edges have their parent edges? Names what is missing.

    PropertyTypeDescription
    key
    required
    stringThe work item to validate — the project key, a dash, the number (e.g. "ACME-7"), case-insensitive. With `planId`, this may instead be a `planItem:<id>` temp-ref naming an `add` in that plan (case-SENSITIVE, as `add_plan_items` returned it).
    condition
    optional
    string
    loose · tight
    How strict to be about a DONE gating item that sits OUTSIDE the set (sprint / subtree). `loose` (default): a done item outside the set counts as satisfied. `tight`: only an in-set item satisfies — a done item outside the set is reported as a blocker.
    planId
    optional
    stringOPTIONAL — the id of a plan (as returned by `create_plan`) to PROJECT over. When given, the answer is computed over the project’s live tree ⊕ that plan’s proposals, so an agent can check the tree it is proposing BEFORE anyone reviews it. Omit it for the committed tree — a call without this argument behaves exactly as it did before projection existed. Nothing is created, mutated or persisted either way, and a proposal never becomes a work item except by approving the plan in Motir.
  • whoamiWho am ILesezugriffe

    Who this token is: the owning user, the active workspace, and the scopes granted. Call it first.

    Takes no arguments.

View the lesson library

Read what the project's AI planner learned from its own planning work. · granted by default

  • search_lessonsSearch lessons by meaningDestruktiv

    Search recorded lessons by meaning — the shared corpus and this project's own — narrowed by kind, type, phase and subject, before you plan or build.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the sprint belongs to — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value.
    query
    required
    stringYour question, in TAKEAWAY register — the action you are about to take and the SHAPE of what could go wrong, in the words a lesson would be written in: "counting a population from a working tree instead of a ref". NOT the card's title ("board filter at scale"), which queries the wrong register and ranks by accident. This text is what decides which lessons arrive, so it is worth a sentence rather than a phrase. A card with more than one distinct risk deserves more than one search: one call returns a handful, and one query cannot rank for three different failure shapes.
    kinds
    optional
    string[]The LEVEL this search is about: the work-item KIND you are writing or laying under, or "project" / "onboarding" when laying a project's top level ("onboarding" for a first plan carved from the direction docs). Laying a level narrows on the target you lay under, not the kind of its children. Omitting it leaves the axis UNCONSTRAINED, which is often right — a lesson tagged with no kind reaches every query either way.
    types
    optional
    string[]The work TYPE(s) this search is about (code, design, test, …). Omitting it leaves the axis unconstrained.
    phases
    optional
    string[]Which part of a card you are writing: "lay" (laying a level's children — shape, edges, coverage) or "author" (writing a body — criteria, sizing, claims). The retired spellings "skeleton" and "deepen" are still accepted and read as "lay" and "author"; they are removed in a later release. The coordinate only you can supply.
    subject
    optional
    stringWHICH SUBJECT MATTER this search is about — the FOURTH routing axis, the same one `add_lesson` records a lesson against (`data`, `jobs`, `llm`, `mcp`, …). SCALAR: one subject or none, never a list, because a lesson has one. Narrowing on it returns the lessons carrying that subject AND the lessons carrying none — an untagged lesson is MORE general than either subject, so it still reaches every query. Omitting it leaves the axis unconstrained. MEMBERSHIP IS NOT VALIDATED, exactly as on the write side: an unrecognised value is accepted and simply matches no subject-tagged row, so a typo narrows to the untagged lessons rather than erroring.
    limit
    optional
    integerHow many lessons to return, nearest first. Default 8.

Change the lesson library

Retire a lesson or add one — both change the standing instructions the planner is given. · granted by default

  • add_lessonAdd lessonSchreibzugriffe

    Record a lesson for this project, so later plans for it are given the lesson. This project only.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the sprint belongs to — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value.
    title
    required
    stringThe takeaway, in one line — the thing a planner should do differently, not a headline for an incident. "Pin the target repository on every card that ships code" is a lesson; "Repository problems in the billing epic" is a label for one.
    body
    required
    stringWhat goes wrong, stated so it is recognisable the NEXT time rather than recounted from the last. Describe the situation and the failure, not the specific work items it happened to involve.
    why
    required
    stringWhy it matters — the cost of getting it wrong. This is the one field that may carry the specifics of your own case (what it cost, when, on which work), because it is what justifies the rule rather than what a future plan is matched against.
    howToApply
    required
    stringThe actionable rule, addressed to a future planner in the second person: "Before sealing a card that ships code, set its target repository." Not a restatement of the body — if this field reads like the body, the lesson has no rule in it.
    mistakeType
    optional
    string
    onboarding_planning · regular_planning · planning_craft
    Which kind of planning this lesson is for: "regular_planning" (planning an existing project — the usual answer), "onboarding_planning" (drafting a project's first tree), or "planning_craft" (how to plan well, whatever is being planned).
    kinds
    optional
    string[]WHICH LEVEL this lesson is about — a work-item KIND, or "project" / "onboarding" for a mistake made laying a project's top level ("onboarding" when that plan is carved from the direction docs) — and one of the three axes that decide when a future plan is shown it. A mistake made LAYING a level is filed under the level laid under, not the kind of its children. LEAVING IT OUT MEANS "every kind" — occasionally right, and usually the reason a lesson turns up in plans it has nothing to do with. Say what you mean on each axis rather than skipping it.
    types
    optional
    string[]WHICH WORK TYPES this lesson is about (code, design, test, …). Leaving it out means "every type". Under-claiming is as wrong as over-claiming: a lesson typed only "code" stops reaching the chore work it also applies to.
    phases
    optional
    string[]WHICH PLANNING PHASE this lesson is about: "lay" (laying a level's children — shape, edges, coverage) or "author" (writing one card's body — criteria, sizing, claims). Leaving it out means both. The retired spellings "skeleton" and "deepen" are still accepted and read as "lay" and "author"; they are removed in a later release.
    subject
    optional
    stringWHICH SUBJECT MATTER this lesson is about — the FOURTH routing axis, mirroring the rule-pack selector's fourth coordinate so the two corpora stay reachable by one question. Leaving it out means "every subject", and that is the right answer far more often than the vocabulary suggests: a WRONG subject is worse than none, because it makes the lesson unreachable from every card it actually applies to, while an untagged one still reaches all of them. ⚠️ SCALAR, unlike the three axes above — a lesson carries ONE subject or none, never a list, and a payload sending several is REFUSED rather than coerced (a card wanting two subjects is a SPLIT signal, so a lesson captured from one cannot inherit a multiplicity its source never had). A lesson that genuinely applies across subjects carries NONE — it is more general than either, which is what omitting this says. MEMBERSHIP IS NOT VALIDATED: the vocabulary is the rule-pack file set, so a well-formed unrecognised member is accepted and simply never matches a subject-narrowed query. Shape only: a lowercase slug.
    sourceRef
    optional
    stringWhere this lesson came from — a work-item key, a runbook name, a ticket. Also the idempotency key: adding the same lesson again with the same sourceRef returns the existing one instead of a duplicate.

Record a lesson recurrence

Note that a lesson's mistake happened again. It changes nothing the lesson says. · granted by default

  • reinforce_lessonReinforce a lessonDestruktiv

    Record that a lesson you found describes something that just went wrong — whether or not you also change it.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the sprint belongs to — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value.
    lessonId
    required
    stringThe lesson this occurrence matched — the `id` `search_lessons` returns for each ranked row. Take it from that result; do not construct one.
    occurrenceRef
    required
    stringYOUR identifier for the EVENT that just happened — the work item you are running (`MOTIR-123`), or the bug you filed for it. It is what makes this idempotent: the same event recorded twice counts once. It names the occurrence, NOT the lesson.

Edit work items

Create, update, assign and move work items, and transition them on the board. · granted by default

  • add_work_item_todoAdd a to-do stepSchreibzugriffe

    Append one step to the end of a work item’s to-do list.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    text
    required
    stringThe step — ONE operation, in plain text (not Markdown), at most 200 characters. A longer step is two steps, and is refused rather than truncated.
    notesMd
    optional
    stringOptional instructions for this one step, in Markdown, at most 2000 characters — the how, where `text` is the what.
    commandText
    optional
    stringOptional command this step runs, at most 500 characters. Rendered with a copy button on the work item page.
    executor
    optional
    string
    coding_agent · human
    Who this step is for: "human" or "coding_agent". Declarative — it authorizes nothing. Omitted ⇒ the card’s own executor, or "human" when the card has none.
  • attach_fileAttach fileSchreibzugriffe

    Put a file ON a work item — a research findings document, a review’s notes — so a reader sees the deliverable on the work item instead of hunting for a pull request.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    filename
    required
    stringThe file name as a reader should see it, e.g. "findings.md" or "triage.png".
    contentType
    required
    stringThe file’s media type, e.g. "image/png" or "text/markdown". Must be on the upload allowlist; "text/html" is deliberately refused (415) — an HTML design mock has its own publisher.
    contentBase64
    required
    stringThe file’s bytes, base64-encoded.
  • change_kindChange work item kindDestruktiv

    Reclassify a leaf's kind when it is mis-filed — subtask to task, and back.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    kind
    required
    string
    story · task · bug · subtask
    The new work item kind. Must keep the kind-parent matrix legal for both the item's current parent AND all of its children. (This is the hierarchy KIND, NOT the work type — use update_work_item to change type/executor/difficulty.)
  • claim_next_readyClaim next ready work itemDestruktiv

    Atomically claim the next ready subtask in the active sprint: assign it to you and flip it to In Progress.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value. Case-insensitive.
  • claim_work_itemClaim a work itemDestruktiv

    Atomically claim ONE named work item and flip it to In Progress. A lost claim says WHO holds it.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
  • claim_work_item_continueContinue a dead run’s work itemDestruktiv

    Take over a work item whose last run died or stopped at a gate that is now approved, as `motir continue` does: its branch and pull requests, not a fresh start.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
  • claim_work_item_repairClaim a red work item’s repairDestruktiv

    Take the repair lock on a work item with failing pull requests, as `motir fix` does. One fixer at a time.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
  • close_work_item_continueClose a continueDestruktiv

    End your continue of a work item with how it went, so the page shows it and the card can be continued again.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    runId
    required
    stringThe continue run’s id — the `runId` `claim_work_item_continue` answered. Only your own run on this work item is accepted.
    outcome
    required
    string
    drained · completed · max · halted · interrupted · replanned · gated · abandoned
    How the continue ended — the stop reasons the REST close accepts, and the ones `motir continue` closes with: "completed" (the work is delivered), "drained" (a parent continue ran out of ready cards), "max" (it stopped at its card limit), "halted" (you stopped on something you could not get past), "interrupted" (the person stopped you), "replanned" (the card went to Planning), "gated" (it stopped at an approval gate) or "abandoned".
  • close_work_item_repairClose a repairDestruktiv

    End your repair of a work item with how it went, so the page shows it and a new repair may start.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    runId
    required
    stringThe repair run’s id — the `runId` `claim_work_item_repair` answered. Only your own run on this work item is accepted.
    outcome
    required
    string
    green · gave_up · halted · interrupted
    How the repair ended: "green" (the checks pass), "gave_up" (you spent your attempts), "halted" (you stopped on something you could not get past) or "interrupted" (the person stopped you).
  • close_work_item_runClose your run of a work itemDestruktiv

    End your run of a card with how it went; a delivered close records you as the implementer.

    PropertyTypeDescription
    key
    required
    stringThe card you started the run on (e.g. "ACME-7") — the same key `start_work_item_run` took.
    runId
    required
    stringThe run’s id — the `runId` `start_work_item_run` answered.
    outcome
    required
    string
    drained · completed · max · halted · interrupted · replanned · gated
    How the run ended: "completed" (the work is delivered), "drained" (a parent run finished every child it could), "max" (it stopped at a card limit), "halted" (you stopped on something you could not get past), "interrupted" (the person stopped you), "replanned" (the card went to Planning) or "gated" (the remaining work waits on an approval gate — a design, decision, choice, confirmation or manual card not yet decided; Motir records which gates held the run, and a stop at such a gate is never "halted").
  • complete_sessionComplete sessionDestruktiv

    Close out a session branch after its PR merged: every item recorded on it moves to Done.

    PropertyTypeDescription
    sessionBranch
    required
    stringThe session/integration branch name, e.g. "session/ACME-42-run".
    implementationSource
    optional
    string
    byok · manual
    Optional self-reported implementation source: "byok" (an agent on your own machine) or "manual" (a human, no agent). Defaults to "byok" when a harness/model is reported. "hosted" is not accepted here (that is trusted/metered).
    implementationHarness
    optional
    stringOptional self-reported implementation harness (e.g. "opencode", "Claude Code").
    implementationModel
    optional
    stringOptional self-reported implementation model (e.g. "claude", "deepseek").
  • create_acceptance_uploadCreate acceptance uploadLesezugriffe

    Mint a short-lived presigned PUT for a story’s acceptance recording — step 1 of 2, because a video is far larger than a tool argument can carry. Upload the bytes straight to the store, then register the pathname.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    hasTrace
    optional
    booleanTrue to ALSO mint a grant for the Playwright trace (a dev diagnostic beside the video). Defaults to false — mint it only if you actually captured one.
  • create_design_uploadCreate design uploadLesezugriffe

    Mint a short-lived presigned PUT for a design asset too large to send inline — step 1 of 2, because a large asset is more than a tool argument can carry. Upload the bytes straight to the store, then publish the pathname. Refuses a screenshot, a card nothing waits on, and a done design card.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    files
    required
    object[]The files you are about to upload — one grant is minted per entry, in this order.
    withinParentKey
    optional
    stringOn a PARENT-RUN publish only: the container whose branch this belongs to. It asserts the target is one of that container’s children, and is not stored.
  • create_folderCreate folderSchreibzugriffe

    Create a folder at the root or inside another folder; names are unique per level.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the folders belong to (e.g. "ACME").
    name
    required
    stringThe new folder’s name. Unique among the folders at its level.
    parentFolderId
    optional
    string | nullThe folder to create it inside (an id from `list_folders`). Omit or pass null to create it at the project root.
  • create_planOpen a plan to propose intoSchreibzugriffe

    Open a plan to propose into — the reviewable container an agent fills instead of writing items.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value. Case-insensitive.
    title
    optional
    stringOptional short label for the plan — what it is proposing, in a line.
    summary
    optional
    stringOptional longer summary (Markdown) of what this plan proposes and why, shown to the reviewer above the tree. Not write-once: `update_plan` corrects it — and the title — after the fact, on a `generating` or `planned` plan, without touching a proposal.
    plannedWithHarness
    optional
    stringOptional: the harness/tool you are running as (e.g. "Claude Code", "Codex"). Shown to the person reviewing this plan, so they can see it was written by an agent rather than generated by Motir.
    plannedWithModel
    optional
    stringOptional: the model you are running (e.g. "claude-opus-5"). Shown beside the harness.
  • create_work_itemCreate work itemDestruktiv

    Create an epic, story, task, bug or subtask under a parent or in a folder; points, estimate, type, executor, difficulty, repo and obsolescence mark in one call.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the item is created in — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value.
    kind
    required
    string
    epic · story · task · bug · subtask
    The work item kind. Use "epic" (no parentKey) to create a top-level capability area; "bug" under a story/epic to log a defect (the bug-logging protocol).
    title
    required
    stringThe work item title (one line).
    parentKey
    optional
    stringOptional parent work item identifier (e.g. "ACME-3") — must be a kind-legal, same-project parent. Mutually exclusive with folderId.
    folderId
    optional
    stringOptional: the id of a folder (as `list_folders` returns it) to FILE the new item into — the other placement beside parentKey, which it may not be combined with (PLACEMENT_CONFLICT). A filed item is a root, so any kind may be filed, a subtask included. The folder must be in this project: an unknown id is FOLDER_NOT_FOUND, another project's is CROSS_PROJECT_FOLDER.
    descriptionMd
    optional
    stringOptional Markdown description body.
    priority
    optional
    string
    lowest · low · medium · high · highest
    Optional priority (lowest…highest); omit for the project default.
    storyPoints
    optional
    number | nullOptional story-point estimate (the agile sizing number, distinct from a time estimate). A non-negative number ≤ 9999.99 with at most two decimal places; omit (or null) to leave it unestimated.
    estimateMinutes
    optional
    integer | nullOptional estimated minutes of work (the TIME estimate, distinct from story points); omit (or null) to leave it unestimated.
    type
    optional
    string | null
    code · design · test · content · copy · translate · research · review · verification · decision · choice · deploy · manual · legal · chore
    Optional work type (code, design, test, …) — leaf items (task / bug / subtask) only; rejected on a story. Setting a type seeds the executor from the type default unless an explicit executor is also given. Omit (or null) to leave it untyped.
    executor
    optional
    string | null
    coding_agent · human
    Optional executor ("coding_agent" or "human") — leaf items only; overrides the type default when supplied. Omit (or null) to take the type default (or leave it unset when no type is given).
    difficulty
    optional
    string | null
    trivial · low · medium · high
    Optional difficulty — how hard the work is to REASON about, not how big it is: "trivial", "low", "medium" or "high". Leaf items (task / bug / subtask) only; a non-null value on an epic or story is refused (DIFFICULTY_NOT_ALLOWED_ON_KIND). Omit (or null) to leave it unset.
    obsolescence
    optional
    string | null
    outdated · deprecated
    Mark the item as no longer TRUE OF THE CODE: "outdated" (the text no longer describes what shipped; the capability lives on in another shape) or "deprecated" (retired or overturned on purpose — do not build on it). Settable on ANY kind, but ONLY on a FINISHED item — one whose status is in the done category (`done`, `cancelled`, or a custom done-category status); on any other status it is refused (OBSOLESCENCE_REQUIRES_FINISHED) — archive an item nobody will finish instead. A marked item stays finished: moving it out of the done category, or adding a child under it, is refused (MARKED_CARD_CANNOT_REOPEN) until the mark is cleared. null clears it, always. Link the replacing item with link_work_items `supersedes`. A value outside the enum is refused (INVALID_OBSOLESCENCE). Informational: no read hides or re-orders a marked item.
    obsolescenceNoteMd
    optional
    stringnullMarkdown note saying WHY the item is marked (what changed, what to read instead); null clears it. Independent of `obsolescence`: clearing the mark keeps the note.
    targetRepo
    optional
    stringnullOptional: WHICH REPO this item ships in — the bare repo name (e.g. "motir-core") or the "owner/name" form. Must name one of the PROJECT's repositories — a row of its repository set, including one not created yet. A repository connected to the workspace but not linked to this project is rejected, as is an unknown name. This is what routes the CLI to the right checkout at dispatch (one subtask = one repo = one PR). Omit (or null) to leave it unpinned — dispatch then falls back to the project's single established repository, or reports no repo when the project has none or several.
    targetRepos
    optional
    string[]Optional: EVERY repository this item ships in, ORDERED — bare repo names (e.g. ["motir-core", "motir-ai"]) or the "owner/name" form. The FIRST element is the PRIMARY: the one dispatch routes the CLI to. The rest record where the item's other work lands, and the item does not complete until EVERY repository on the list has a pull request merged onto that repository's own default branch. Each element is validated against the project's repository domain; duplicates collapse, blank elements are dropped, and one unknown element rejects the whole write. Use it for a card that legitimately spans repositories — ONE SUBTASK is still ONE REPO, so this is for a story or a task, not a subtask. `[]` is the empty set. MUTUALLY EXCLUSIVE with targetRepo, which IS this list's first element: supplying both is rejected rather than silently resolved.
    targetRepositories
    optional
    string[]Optional: EVERY repository this item ships in, as REFERENCES to the project's repository ROWS — their ids, ORDERED, the FIRST being the PRIMARY the CLI is dispatched into. Prefer this over targetRepos when you have the ids: a reference survives the repository being renamed, and it can name one of two rows that share a role, which a name cannot. The names you read back are what these resolve to. An id outside THIS item's project is rejected (the error lists the project's rows as "id (name)"); duplicates collapse; `[]` is the empty set. MUTUALLY EXCLUSIVE with BOTH targetRepo and targetRepos — they are the same field in three forms, so supplying two is rejected rather than silently resolved.
    plannedWithHarness
    optional
    stringOptional: the harness/tool this item was planned with (e.g. "Claude Code", "Codex"). Recorded as self-reported planning provenance alongside the server-set source "mcp"; omit to leave it unrecorded.
    plannedWithModel
    optional
    stringOptional: the LLM this item was planned with (e.g. "claude-opus-4-8", "deepseek-chat"). Recorded as self-reported planning provenance; omit to leave it unrecorded.
  • delete_folderDelete folderDestruktiv

    Delete a folder; its folders and work items move up, and the result lists what moved.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the folders belong to (e.g. "ACME").
    folderId
    required
    stringThe folder id (as returned by `list_folders`).
  • delete_work_item_todoDelete a to-do stepDestruktiv

    Permanently delete one step of a work item’s to-do list.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    todoId
    required
    stringThe step’s id, as `list_work_item_todos` or `add_work_item_todo` returned it. A step on another work item is refused as not found.
  • link_pull_requestLink pull requestDestruktiv

    Declare which work item a pull request delivers — call it right after opening one, once per work item it delivers. The association is a SET, so a second call ADDS rather than moving, and it works before any webhook delivery has arrived.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    repository
    optional
    stringThe repository as "owner/name", exactly as it is connected in Motir (case-insensitive). Give this WITH `number`, or give `url` instead — not neither.
    number
    optional
    integerThe pull-request number, e.g. 2291. Give this with `repository`.
    url
    optional
    stringThe full pull-request URL, e.g. "https://github.com/acme/web/pull/2291" — the line `gh pr create` prints, so it can be passed through verbatim. An alternative to `repository` + `number`, never a supplement: if both are given they must agree.
    headRef
    required
    stringThe branch the pull request is FROM, e.g. "subtask/ACME-7-widget". Used only when no webhook delivery has arrived yet and this call is what creates the row; once a delivery has landed, the delivery is authoritative and this is ignored.
    baseRef
    required
    stringThe branch the pull request TARGETS, e.g. "main". Same rule as `headRef`: it seeds the row when there is none, and a later delivery overwrites it.
    title
    optional
    stringThe pull request’s title, for the row this call may have to create. Optional — the first webhook delivery supplies the real one either way.
  • link_work_itemsLink work itemsSchreibzugriffe

    Create an edge between two items — blocked_by is the one that holds an item out of the ready set.

    PropertyTypeDescription
    fromKey
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    toKey
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    relationship
    required
    string
    blocked_by · blocks · relates_to · duplicates · clones · supersedes · superseded_by
    The relationship FROM the first item TO the second, read "fromKey <relationship> toKey": "blocked_by" (fromKey is blocked by toKey — the dependency edge that holds fromKey out of the ready set), "blocks" (the inverse — fromKey blocks toKey), "relates_to", "duplicates", "clones", "supersedes" (fromKey is the NEWER work item that replaces toKey), or "superseded_by" (the inverse — fromKey is the OLDER item, replaced by toKey). The supersedes pair is one stored edge read from either end; it gates nothing.
  • mark_integratedMark integratedDestruktiv

    Record that an item's work landed — the branch, the PR and the commit that carried it.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    sessionBranch
    required
    stringThe session/integration branch name, e.g. "session/ACME-42-run".
    implementationSource
    optional
    string
    byok · manual
    Optional self-reported implementation source: "byok" (an agent on your own machine) or "manual" (a human, no agent). Defaults to "byok" when a harness/model is reported. "hosted" is not accepted here (that is trusted/metered).
    implementationHarness
    optional
    stringOptional self-reported implementation harness (e.g. "opencode", "Claude Code").
    implementationModel
    optional
    stringOptional self-reported implementation model (e.g. "claude", "deepseek").
  • move_to_parentMove work item to a new parentDestruktiv

    Re-place an item — under a new parent, or into or out of a folder — enforcing the kind-parent matrix and refusing a cycle.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    parentKey
    optional
    string | nullThe NEW parent work item identifier (e.g. "ACME-3") — must be a kind-legal, same-project parent, and may not be the item itself or one of its descendants. Pass null to promote the item to a top-level root (allowed only for kinds that may live at the top level; a filed item keeps its folder). Give EXACTLY ONE of parentKey and folderId.
    folderId
    optional
    string | nullThe id of a folder (as `list_folders` returns it) to FILE the item into, or null to take it OUT of its folder to the top level. Filing clears the work-item parent; the item's own children travel with it. Give EXACTLY ONE of parentKey and folderId. An unknown folder is FOLDER_NOT_FOUND, another project's CROSS_PROJECT_FOLDER.
  • move_work_item_todoMove a to-do stepDestruktiv

    Move one step of a work item’s to-do list to a new position.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    todoId
    required
    stringThe step’s id, as `list_work_item_todos` or `add_work_item_todo` returned it. A step on another work item is refused as not found.
    toIndex
    required
    integerWhere the step goes: its 0-based position in the list as it reads AFTER the move (0 is first). Read against the current list, not the one you last listed; an index past either end is clamped to that end.
  • publish_acceptance_resultPublish acceptance resultDestruktiv

    Register the uploaded recording as the story’s acceptance receipt — the thing a reviewer watches and the gate rests on. Nothing else publishes it, and a missing publish looks exactly like a successful run.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    videoPathname
    required
    stringThe `pathname` of the video grant you uploaded to, exactly as it was returned.
    tracePathname
    optional
    stringThe trace grant’s `pathname`, when one was minted and uploaded to.
    chapters
    optional
    object[]The chapter markers, from the run’s `chapters.json` — what the reviewer scrubs by. A receipt with none is watchable but not navigable, so send them when the spec wrote them.
    commitSha
    optional
    stringThe commit the run recorded at, as 7 to 64 HEX characters — a full object id or an abbreviation of it, never a branch name or "HEAD". Surrounding whitespace and upper-case hex are accepted and stored normalised; anything else is refused naming this field. ALSO THE IDEMPOTENCY KEY: re-publishing the same commit + producedByKey returns the existing receipt instead of superseding it — which is why it is stored canonical, so two spellings of one commit are one key. The format is checked; whether the commit EXISTS is not.
    producedByKey
    optional
    stringThe E2E work item that produced the recording, e.g. "ACME-7".
  • publish_decision_pagePublish decision pageSchreibzugriffe

    Publish a page as a decision card’s decision: seals its newest version and, on an agent card, asks a person to approve it.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    pageId
    required
    stringThe page id — the `<id>` in the page’s address `/pages/<id>`.
  • publish_design_resultPublish design resultDestruktiv

    Put the design RESULT on a design work item — the mock(s) and the area note as a link, what a reviewer opens — only when an open work item is blocked_by the design. No .png and no inline note: both are refused, and so is a done design card, which accepts no new version. Each asset arrives inline as base64, or as the pathname of a create_design_upload grant when it is too large to send.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    assets
    required
    object[]The files to publish: one or more mocks (for a change to an existing design, the NEW delta mock(s) only) and exactly one "note_file". Each entry carries EITHER `contentBase64` (the bytes inline, for a small asset) OR the `pathname` of a `create_design_upload` grant you have already PUT to. One publish uses one of the two forms for ALL its assets.
    noteMd
    optional
    stringRETIRED — do not send it. A design result no longer carries the note inline: publish the notes file as the one "note_file" asset and the result links to it. Present only so a caller still sending it is refused by name (DESIGN_EVIDENCE_NOTE_MD_RETIRED) rather than silently ignored.
    commitSha
    optional
    stringThe commit the assets were published from, as 7 to 64 HEX characters — a full object id or an abbreviation of it, never a branch name or "HEAD". Surrounding whitespace and upper-case hex are accepted and stored normalised; anything else is refused naming this field. ALSO THE IDEMPOTENCY KEY: re-publishing the same commit + producedByKey returns the existing result instead of superseding it — which is why it is stored canonical, so two spellings of one commit are one key and a reviewer mid-review does not lose the version they were answering about. The format is checked; whether the commit EXISTS is not.
    producedByKey
    optional
    stringThe work item whose pull request produced this result, e.g. "ACME-7".
    withinParentKey
    optional
    stringOn a PARENT-RUN publish only: the container whose branch this belongs to. It asserts the target is one of that container’s children, and is not stored.
  • publish_test_instructionsPublish How to testDestruktiv

    Put a RUN’s HOW TO TEST onto its run target — before the run finishes, and again when a later commit changes a step: rich-text Markdown with sections and every command in a fenced code block (click-to-copy), plus the commit of each repository it pushed to.

    PropertyTypeDescription
    key
    required
    stringThe RUN TARGET — the work item the run was launched against (e.g. "ACME-7"): the story for a story or scoped run, the card itself for a single-card run. Case-insensitive.
    bodyMd
    required
    stringHow to test this run, as Markdown. Use SECTIONS — e.g. "## Precondition" (the sign-in, role or data the surface needs), "## Locally" (setup after checking out the branch: install, migrate, seed, run) and "## Click-path" (what to open, click and expect to SEE) when the run creates or changes a rendered surface; otherwise say why there is none. Put EVERY command in its own fenced code block — the page renders each with a click-to-copy control. Do NOT include the branch fetch: Motir composes it from each pull request. At most 32 KiB.
    repos
    optional
    object[]One entry per repository the run pushed to, at most 8, each with its pushed head commit. Optional only because a PERSON writing from the form names no repository; SEND ONE PER REPOSITORY YOU PUSHED TO — your record is the evidence for the delivery set a person approves.
    previewPath
    optional
    stringThe path to open on the preview deployment, starting with "/" — e.g. "/items/ACME-7". A path, never a URL: Motir joins it onto the preview the host reported. At most 500 characters.
  • report_actionReport your next stepSchreibzugriffe

    Say the step you are about to take on a card, record a milestone, or send a heartbeat for your open runs.

    PropertyTypeDescription
    key
    optional
    stringThe card the step is on (e.g. "ACME-7") — the card you started the run on, or one of its children in a parent run. Required with `action` or `events`; omit everything for a heartbeat only.
    action
    optional
    stringThe step you are ABOUT to take, in one line of at most 500 characters — e.g. "Running the targeted tests for the run service". Never a transcript, a diff, file contents, a prompt or a secret.
    events
    optional
    object[]Milestones to record before the step, on the leg of `key`.
  • report_unbuildable_targetReport a card you cannot buildDestruktiv

    A dispatched runner reports the card it stopped on as unbuildable — acknowledged, nothing to act on.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value. Case-insensitive.
    targetKey
    required
    stringThe card you stopped on — the one you were dispatched to build (e.g. "ACME-7"). Case-insensitive.
    reason
    required
    stringWhy the card cannot be built — the SAME text as the comment you left on it (1–4000 characters once trimmed). Describe what is wrong with the CARD.
  • set_work_item_todo_doneTick or untick a to-do stepDestruktiv

    Tick or untick one step of a work item’s to-do list. Ticking the last step does not change the work item’s status.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    todoId
    required
    stringThe step’s id, as `list_work_item_todos` or `add_work_item_todo` returned it. A step on another work item is refused as not found.
    done
    required
    booleantrue ticks the step; false unticks it.
  • start_work_item_runStart your run of a work itemSchreibzugriffe

    Open your own run of a card you hold, naming your harness and model, so it shows on Runs and on the card.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    harness
    required
    stringThe agent harness you are running in, as its makers name it — e.g. "Claude Code", "Codex", "Kimi CLI". Say what you are, honestly; it is what the run and the card record.
    model
    optional
    stringThe model you are running on, by its id (e.g. "gpt-5-codex"). Omit it when you do not know it rather than guessing.
  • touch_work_item_continueKeep a continue aliveDestruktiv

    Keep your continue of a work item alive. A continue silent for five minutes is closed and its lock released.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    runId
    required
    stringThe continue run’s id — the `runId` `claim_work_item_continue` answered. Only your own run on this work item is accepted.
  • touch_work_item_repairKeep a repair aliveDestruktiv

    Keep your repair of a work item alive. A repair silent for five minutes is closed and its lock released.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    runId
    required
    stringThe repair run’s id — the `runId` `claim_work_item_repair` answered. Only your own run on this work item is accepted.
  • transition_statusTransition statusDestruktiv

    Move an item to another status. An illegal move comes back naming the ones that are legal.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    status
    required
    stringThe target status — its key (e.g. "in_progress") or display name (e.g. "In progress").
  • unlink_pull_requestUnlink pull requestDestruktiv

    Undo ONE `link_pull_request` — remove the delivery recorded between a work item and a pull request. A delivery is a row, so re-linking the right work item ADDS rather than corrects; this removes exactly the one pair you name and leaves every other delivery alone.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    repository
    optional
    stringThe repository as "owner/name", exactly as it is connected in Motir (case-insensitive). Give this WITH `number`, or give `url` instead — not neither.
    number
    optional
    integerThe pull-request number, e.g. 2291. Give this with `repository`.
    url
    optional
    stringThe full pull-request URL, e.g. "https://github.com/acme/web/pull/2291". An alternative to `repository` + `number`, never a supplement: if both are given they must agree.
  • unlink_work_itemsUnlink work itemsDestruktiv

    Remove an edge, given the same relationship used to create it.

    PropertyTypeDescription
    fromKey
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    toKey
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    relationship
    required
    string
    blocked_by · blocks · relates_to · duplicates · clones · supersedes · superseded_by
    The relationship FROM the first item TO the second, read "fromKey <relationship> toKey": "blocked_by" (fromKey is blocked by toKey — the dependency edge that holds fromKey out of the ready set), "blocks" (the inverse — fromKey blocks toKey), "relates_to", "duplicates", "clones", "supersedes" (fromKey is the NEWER work item that replaces toKey), or "superseded_by" (the inverse — fromKey is the OLDER item, replaced by toKey). The supersedes pair is one stored edge read from either end; it gates nothing.
  • update_folderUpdate folderDestruktiv

    Rename a folder, or move and reorder it — one or the other per call, never both.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the folders belong to (e.g. "ACME").
    folderId
    required
    stringThe folder id (as returned by `list_folders`).
    name
    optional
    stringRENAME: the folder’s new name. Do not combine with a placement.
    parentFolderId
    optional
    string | nullPLACE: the folder to move it into (an id from `list_folders`), or null for the project root. Omit to keep its current parent and only reorder it. Do not combine with `name`.
    beforeId
    optional
    string | nullPLACE: the sibling folder this one should sort AFTER.
    afterId
    optional
    string | nullPLACE: the sibling folder this one should sort BEFORE.
  • update_work_itemUpdate work itemDestruktiv

    Edit any subset of an item's fields, including the explanation body create cannot set.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    title
    optional
    stringNew title (one line).
    descriptionMd
    optional
    stringnullNew Markdown description body; null clears it.
    explanationMd
    optional
    stringnullNew Markdown explanation body (the "why"); null clears it.
    priority
    optional
    string
    lowest · low · medium · high · highest
    New priority (lowest…highest).
    type
    optional
    string | null
    code · design · test · content · copy · translate · research · review · verification · decision · choice · deploy · manual · legal · chore
    New work type (code, design, test, …) — leaf items only; null clears it. Setting a type the first time seeds the executor from the type default.
    executor
    optional
    string | null
    coding_agent · human
    Who executes the work ("coding_agent" or "human") — leaf items only; null clears it.
    difficulty
    optional
    string | null
    trivial · low · medium · high
    How hard the work is to REASON about, not how big it is: "trivial", "low", "medium" or "high" — leaf items only; null clears it. A non-null value on an epic or story is refused (DIFFICULTY_NOT_ALLOWED_ON_KIND), and so is changing the kind of a leaf that carries one to a container without clearing it in the same call.
    obsolescence
    optional
    string | null
    outdated · deprecated
    Mark the item as no longer TRUE OF THE CODE: "outdated" (the text no longer describes what shipped; the capability lives on in another shape) or "deprecated" (retired or overturned on purpose — do not build on it). Settable on ANY kind, but ONLY on a FINISHED item — one whose status is in the done category (`done`, `cancelled`, or a custom done-category status); on any other status it is refused (OBSOLESCENCE_REQUIRES_FINISHED) — archive an item nobody will finish instead. A marked item stays finished: moving it out of the done category, or adding a child under it, is refused (MARKED_CARD_CANNOT_REOPEN) until the mark is cleared. null clears it, always. Link the replacing item with link_work_items `supersedes`. A value outside the enum is refused (INVALID_OBSOLESCENCE). Informational: no read hides or re-orders a marked item.
    obsolescenceNoteMd
    optional
    stringnullMarkdown note saying WHY the item is marked (what changed, what to read instead); null clears it. Independent of `obsolescence`: clearing the mark keeps the note.
    estimateMinutes
    optional
    integer | nullEstimated minutes of work; null clears it.
    storyPoints
    optional
    number | nullStory-point estimate (the agile sizing number, distinct from the time estimate above): a non-negative number ≤ 9999.99 with at most two decimal places. null clears it.
    targetRepo
    optional
    stringnullWHICH REPO this item ships in — the bare repo name (e.g. "motir-core") or the "owner/name" form; must name one of the PROJECT's repositories — a row of its repository set, including one not created yet. A repository connected to the workspace but not linked to this project is rejected. Routes the CLI to the right checkout at dispatch (one subtask = one repo = one PR). null clears the pin.
    targetRepos
    optional
    string[]Replace the repository SET wholesale — EVERY repository this item ships in, ORDERED, the FIRST element being the PRIMARY the CLI is dispatched into. The item does not complete until every repository on the list has a pull request merged onto that repository's own default branch, so use it for a card that legitimately spans repositories (a story or a task — ONE SUBTASK is still ONE REPO). Same validation as create; `[]` clears the set. MUTUALLY EXCLUSIVE with targetRepo, which IS this list's first element: supplying both is rejected rather than silently resolved.
    targetRepositories
    optional
    string[]Replace the repository set wholesale, as REFERENCES to the project's repository ROWS — their ids, ORDERED, the FIRST being the PRIMARY the CLI is dispatched into. Prefer this over targetRepos when you have the ids: a reference survives a rename and can name one of two rows sharing a role. Same validation as create; `[]` clears the set. MUTUALLY EXCLUSIVE with BOTH targetRepo and targetRepos.
    assigneeId
    optional
    stringnullNew assignee user id (must be a workspace member); null unassigns.
    dueDate
    optional
    stringnullDue date as an ISO-8601 string; null clears it.
  • update_work_item_todoEdit a to-do stepDestruktiv

    Edit one step of a work item’s to-do list. Only the fields you send change; null clears an optional one.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    todoId
    required
    stringThe step’s id, as `list_work_item_todos` or `add_work_item_todo` returned it. A step on another work item is refused as not found.
    text
    optional
    stringThe step’s new text — ONE operation, in plain text, at most 200 characters. Omitted ⇒ unchanged.
    notesMd
    optional
    stringnullNew instructions for the step, in Markdown, at most 2000 characters. Omitted ⇒ unchanged; null clears them.
    commandText
    optional
    stringnullNew command for the step, at most 500 characters. Omitted ⇒ unchanged; null clears it.
    executor
    optional
    string | null
    coding_agent · human
    Who the step is for: "human" or "coding_agent". Omitted ⇒ unchanged; null clears it.

Archive work items

Archive a work item and restore it later. Affects that item only — its children stay. · granted by default

  • archive_work_itemArchive work itemDestruktiv

    Soft-remove an item: it leaves the ready set and search, and stays fully restorable.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
  • unarchive_work_itemUnarchive work itemDestruktiv

    Restore an archived item — the inverse of archive.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.

Delete work items

Permanently delete a work item and everything beneath it. Cannot be undone.

  • delete_work_itemDelete work itemDestruktiv

    Permanently delete an item and its whole subtree. Irreversible, and off by default.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.

Add comments

Post comments on work items, and edit or delete your own. · granted by default

  • add_commentAdd commentDestruktiv

    Post a Markdown comment as the token owner. Mentions notify the member named.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    body
    required
    stringThe comment body (Markdown). Mention a member with @[name](userId).
  • delete_commentDelete commentDestruktiv

    Permanently delete a comment you wrote, with its replies. Only its author can delete it here.

    PropertyTypeDescription
    commentId
    required
    stringThe comment id — the `id` `add_comment` returned, or a comment row’s `id` from `get_work_item_activity`.
  • edit_commentEdit commentDestruktiv

    Replace the body of a comment you wrote. Only its author can edit it here.

    PropertyTypeDescription
    commentId
    required
    stringThe comment id — the `id` `add_comment` returned, or a comment row’s `id` from `get_work_item_activity`.
    body
    required
    stringThe new comment body (Markdown). Mention a member with @[name](userId).

Read pages

Open and read the project's pages. · granted by default

  • get_pageGet pageLesezugriffe

    Read one page as markdown — its title, where it is filed, its revision and newest version — to read it or to write it back; or read one version by number.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the page belongs to (e.g. "ACME").
    pageId
    required
    stringThe page id — the `<id>` in the page’s address `/pages/<id>`.
    version
    optional
    integerA version NUMBER (from the page’s history). Returns that version’s markdown, number, author, `savedAt`, and whether it is `sealed` (published for a decision) or `frozen` (approved). Omit to read the current body.

Edit pages

Create pages, rename them and change what they say. · granted by default

  • create_pageCreate pageSchreibzugriffe

    Create a page with a markdown body — at the root, in a folder or as a sub-page — and get its id and revision.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the page belongs to (e.g. "ACME").
    title
    optional
    stringThe page’s title. Omit for an untitled page; rename it in the editor later.
    markdown
    optional
    stringThe page’s body as markdown. Omit for an empty page.
    parent
    optional
    objectWhere to file the page: `{ "kind": "root" }`, `{ "kind": "folder", "id": … }` or `{ "kind": "page", "id": … }` for a sub-page. Omit to file it at the project root.
  • update_pageUpdate pageSchreibzugriffe

    Replace a page’s whole body with markdown at the revision you read; a page saved since is refused, not merged.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the page belongs to (e.g. "ACME").
    pageId
    required
    stringThe page id — the `<id>` in the page’s address `/pages/<id>`.
    markdown
    required
    stringThe page’s WHOLE new body as markdown. It replaces the body; it is not appended.
    revision
    required
    integerThe `revision` your `get_page` (or `create_page`) returned. A page saved since is refused PAGE_REVISION_CONFLICT and nothing is written.

Manage sprints

Start and complete Sprints, and rank the backlog. · granted by default

  • complete_sprintComplete sprintDestruktiv

    Complete the active sprint.

    PropertyTypeDescription
    sprintId
    required
    stringThe sprint id (as returned by `list_sprints`).
    carryOverTo
    required
    string | objectREQUIRED disposition for unfinished items: "backlog" (move them to the backlog) or { "sprintId": "<id>" } to move them into another PLANNED sprint in the same project. Done items always stay on the completed sprint.
  • create_sprintCreate sprintSchreibzugriffe

    Create a planned sprint on a project, with an optional name, goal and planned window.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the sprint belongs to — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value.
    name
    optional
    stringOptional sprint name; defaults to "Sprint <n>" (the next sequence).
    goal
    optional
    stringOptional sprint goal.
    startDate
    optional
    stringOptional planned start (ISO-8601). A planned sprint activates on start_sprint.
    endDate
    optional
    stringOptional planned end (ISO-8601); must be ≥ startDate.
  • delete_sprintDelete sprintDestruktiv

    Delete a planned or complete sprint.

    PropertyTypeDescription
    sprintId
    required
    stringThe sprint id (as returned by `list_sprints`).
  • move_to_backlogMove work items to backlogDestruktiv

    Move items out of their sprint and back to the backlog.

    PropertyTypeDescription
    keys
    required
    string[]Work item identifiers to move to the backlog, e.g. ["ACME-7", "ACME-8"].
  • move_to_sprintMove work items to sprintDestruktiv

    Add items to a sprint in one atomic move, appended in the order given.

    PropertyTypeDescription
    keys
    required
    string[]Work item identifiers to move, e.g. ["ACME-7", "ACME-8"].
    sprintId
    required
    stringThe sprint id (as returned by `list_sprints`).
  • start_sprintStart sprintDestruktiv

    Start a planned sprint, making it the project's active one.

    PropertyTypeDescription
    sprintId
    required
    stringThe sprint id (as returned by `list_sprints`).
    name
    optional
    stringOptional rename on start.
    goal
    optional
    stringnullOptional goal edit on start; null clears it, omit to leave unchanged.
    startDate
    optional
    stringOptional start (ISO-8601); defaults to now.
    endDate
    optional
    stringOptional planned end (ISO-8601); must be ≥ startDate.
  • update_sprintUpdate sprintDestruktiv

    Rename a sprint, change its goal, or adjust its planned window.

    PropertyTypeDescription
    sprintId
    required
    stringThe sprint id (as returned by `list_sprints`).
    name
    optional
    stringNew name (omit to leave unchanged).
    goal
    optional
    stringnullNew goal; null clears it, omit to leave unchanged.
    startDate
    optional
    stringnullNew planned start (ISO-8601); null clears it, omit to leave unchanged.
    endDate
    optional
    stringnullNew planned end (ISO-8601, ≥ startDate); null clears it, omit to leave unchanged.

Run AI planning

Submit a planning job that spends the workspace’s AI credits and proposes plan changes. · granted by default

  • append_plan_turnAdd a planning turnDestruktiv

    Add one turn to a planning conversation, named by its session id — what you want changed about the plan.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value. Case-insensitive.
    targetKeys
    optional
    string[]Optional work-item identifiers (e.g. ["ACME-7", "ACME-9"], case-insensitive) to ANCHOR the conversation at. Omit for the project-wide planning thread. The anchor SET describes what the conversation is about — order and duplicates do not matter.
    sessionId
    optional
    stringOPTIONAL. The `id` of the planning session to address — the `id` that `open_plan_session`, `append_plan_turn` and `submit_plan_session` return. Pass it on every later call to keep talking to the SAME conversation. Omit it to use your own recent session for this scope (active in the last 2 hours), or to start a new one.
    body
    required
    stringWhat to say in this turn — what you want changed about the plan.
  • code_exploreExplore the code graphLesezugriffe

    The hosted code graph around a query — the hosted planner's own answer, paged, every absence a named state.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the sprint belongs to — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value.
    query
    required
    stringWhat to look for: a symbol, a concept, or a few words naming the code you want.
    repo
    optional
    stringOPTIONAL. Limit the read to ONE repository in the project’s set — its bare name ("motir-core") or `owner/name`, case-insensitively. Omit to read every indexed repository in the set.
    cursor
    optional
    stringOPTIONAL. Fetch the NEXT PAGE of an earlier result: pass the `cursor` printed on that result’s page line, exactly as printed, with the same other arguments. Omit for page 1.
  • code_searchSearch the code graphLesezugriffe

    Symbols matching a name in the hosted code graph — the hosted planner's own answer, paged.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the sprint belongs to — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value.
    query
    required
    stringWhat to look for: a symbol, a concept, or a few words naming the code you want.
    repo
    optional
    stringOPTIONAL. Limit the read to ONE repository in the project’s set — its bare name ("motir-core") or `owner/name`, case-insensitively. Omit to read every indexed repository in the set.
    cursor
    optional
    stringOPTIONAL. Fetch the NEXT PAGE of an earlier result: pass the `cursor` printed on that result’s page line, exactly as printed, with the same other arguments. Omit for page 1.
    limit
    optional
    integerOPTIONAL. The page size — how many symbols to return per page.
  • expand_itemExpand work itemDestruktiv

    Submit an AI expansion of one container item. Spends the owner's credits; proposals await approval.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
  • get_code_healthGet code healthLesezugriffe

    Each repository's index state, latest code-health audit summary and derived coding convention — what the hosted planner reads.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the sprint belongs to — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value.
  • open_plan_sessionOpen plan conversationDestruktiv

    Open a planning conversation — by its id, your recent one, or a new one — and read its thread.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value. Case-insensitive.
    targetKeys
    optional
    string[]Optional work-item identifiers (e.g. ["ACME-7", "ACME-9"], case-insensitive) to ANCHOR the conversation at. Omit for the project-wide planning thread. The anchor SET describes what the conversation is about — order and duplicates do not matter.
    sessionId
    optional
    stringOPTIONAL. The `id` of the planning session to address — the `id` that `open_plan_session`, `append_plan_turn` and `submit_plan_session` return. Pass it on every later call to keep talking to the SAME conversation. Omit it to use your own recent session for this scope (active in the last 2 hours), or to start a new one.
  • read_fileRead a fileLesezugriffe

    One file's text from a repository in the project's set, at a ref — capped and line-ranged like the hosted planner's read, every absence a named outcome.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key the sprint belongs to — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value.
    repo
    required
    stringThe repository to read from — one in this project’s set, by its bare name ("motir-core") or as `owner/name`, case-insensitively. `get_code_health` and `get_project_state` list the set.
    path
    required
    stringThe file path RELATIVE TO THE REPOSITORY ROOT, e.g. "lib/git/provider.ts". Not a URL, not an absolute path, and never containing "..".
    ref
    optional
    stringOPTIONAL. The branch, tag or commit to read at. Omit for the repository’s default branch — the MERGED code. To read a card’s UNMERGED code, pass the branch its pull request is on.
    startLine
    optional
    integerOPTIONAL, 1-based and inclusive. Read from this line.
    endLine
    optional
    integerOPTIONAL, 1-based and inclusive. Read up to this line. Omit with `startLine` set to read to the end of the file.
  • submit_plan_sessionSubmit plan conversationDestruktiv

    Send the conversation's accumulated intent to the planner as one change set.

    PropertyTypeDescription
    projectKey
    required
    stringThe project key — the prefix chosen for that project at creation (e.g. "ACME"), not a reserved value. Case-insensitive.
    targetKeys
    optional
    string[]Optional work-item identifiers (e.g. ["ACME-7", "ACME-9"], case-insensitive) to ANCHOR the conversation at. Omit for the project-wide planning thread. The anchor SET describes what the conversation is about — order and duplicates do not matter.
    sessionId
    optional
    stringOPTIONAL. The `id` of the planning session to address — the `id` that `open_plan_session`, `append_plan_turn` and `submit_plan_session` return. Pass it on every later call to keep talking to the SAME conversation. Omit it to use your own recent session for this scope (active in the last 2 hours), or to start a new one.
    requirement
    optional
    objectOPTIONAL. WHAT you want built, as six named fields instead of prose — the planner reads this INSTEAD of asking you what is wrong. Supply as much as you actually know: nothing here is validated, and a partial requirement submits fine. Three fields (`outcome`, `behaviour`, `acceptance`) must be present and non-empty for the planner to treat the requirement as settled; short of that it simply opens the conversation, which is the same thing it does when you omit this argument entirely.

Author AI plans

Add proposals to a generated plan and close it for review. Reading a plan needs only project access. · granted by default

  • add_plan_itemsAppend proposals to a planDestruktiv

    Append proposals to a plan — close it with an empty final batch, or add to one you already closed with `revision: true`; ids come back in order, so the next batch can hang children off them. A `modify` may also mark a FINISHED card outdated or deprecated, with a note and supersedes edges (an `add` names the cards it replaces in `supersedesRefs`), refs as a key, an id or a `planItem:` ref; marking an unfinished card is refused — remove it instead.

    PropertyTypeDescription
    planId
    required
    stringThe plan id `create_plan` returned.
    proposals
    required
    object[]The batch to append, in the order you want their ids back. MAY be empty — but ONLY together with `final: true`, which is how a titles-first pass CLOSES a plan it has finished writing.
    final
    optional
    booleanSet true on the LAST batch to close the plan (`generating` → `planned`), which is what puts it in front of a person for review. After that, an append needs `revision: true`. Send it with an EMPTY `proposals` array to close a plan you have nothing left to append to.
    revision
    optional
    booleanSet true to append to a plan you have ALREADY closed — a plan that is `planned` and in the review queue. Without it such an append is refused. The plan does NOT re-open: it is `planned` before, during and after, and the append is recorded on its timeline with the harness and model that made it, so the reviewer can see a card arrived after they started reading. It cannot be combined with `final` (the plan is already closed) and requires at least one proposal (there is nothing else it could mean). On a `generating` plan it is unnecessary and simply does nothing. `approved` and `declined` stay frozen.
  • get_approved_shape_verdictIs this card still what its plan approved?Lesezugriffe

    Is this card still what its last approved plan approved? Its plan history and the verdict.

    PropertyTypeDescription
    key
    required
    stringThe work item identifier — the project key, a dash, the number (e.g. "ACME-7"). Case-insensitive.
    childKeys
    optional
    string[]OPTIONAL — the keys of `key`'s CHILDREN you want a verdict on too (at most 49), typically the ones a parent-run found wrong. Each must be a direct child of `key`: one that is not is REFUSED with `APPROVED_SHAPE_NOT_A_CHILD` naming it, never silently dropped or answered.
    historyCursor
    optional
    stringOPTIONAL — the `planHistory.nextCursor` a previous call returned, for the next page of the card's plan history. The verdict does not depend on it: it is always computed over the WHOLE history.
  • record_plan_revision_reasonRecord WHY a plan had to changeSchreibzugriffe

    Record WHY an unapproved plan had to change — four branches, two of which file a planning bug; it changes nothing about the plan.

    PropertyTypeDescription
    planId
    required
    stringThe plan id `create_plan` returned.
    branch
    required
    string
    new_ask · different_solution · rule_gap · rule_not_followed
    WHY this plan has to change. `new_ask` — the person now wants something the conversation that settled the plan never raised. `different_solution` — the plan answered what was asked and they prefer another answer. `rule_gap` — the plan missed a check and NO planning rule asks for it; its fix is a new rule. `rule_not_followed` — a rule requires the check and this pass did not apply it. The first two are about the person and file NO planning bug; the last two are about the planner and each file exactly one.
    evidenceMd
    required
    stringWHY you chose that branch, in Markdown — required on every branch. For `new_ask` / `different_solution`, quote the turn that raised the thing or say that none did. For the two rule branches, quote the rule SEARCH: choosing between them, and ruling both out, is a search and not a judgement, and a gap asserted without one is an unverified negative.
    planningBugKey
    optional
    stringThe planning bug you filed, by its key (`MOTIR-123`) — REQUIRED on `rule_gap` and `rule_not_followed`, and REFUSED on the other two. File it first with `create_work_item` into the project’s `Planning bugs` folder, then pass its key here so the classification points at the record it produced.
  • report_plan_stepReport the step a planner session is onSchreibzugriffe

    Report the step a planner session is on (settle, lay, author) or end it — an advisory progress signal on a generating plan.

    PropertyTypeDescription
    planId
    required
    stringThe plan id `create_plan` returned.
    sessionKey
    required
    stringA stable name for the planner SESSION reporting the step (at most 128 characters) — one per concurrently running session, so several sessions of one parallel level each hold their own step. A second report under the same key REPLACES that session’s step.
    step
    required
    string
    settle · lay · author · end
    The step the session is starting: `settle` (settling the brief — never a target), `lay` (laying the children of `target`, or the project’s top level with no target), `author` (writing `target`, or an item not on the plan yet with no target), or `end` (the session finished — clears its step; never a target).
    target
    optional
    stringWhat the step works on: a `planItem:<id>` ref naming an `add` on THIS plan, or a committed work item in the plan’s project by its KEY (`MOTIR-123`) or id. Leave it out on `lay` for the project’s top level and on `author` for an item not yet on the plan. Refused on `settle` and `end`.
  • update_planCorrect a plan's own title and summaryDestruktiv

    Correct a plan's OWN title and summary — the heading above the tree — without touching a single proposal.

    PropertyTypeDescription
    planId
    required
    stringThe plan id `create_plan` returned.
    title
    optional
    string | nullThe plan's own short label — what it is proposing, in a line. `null` clears it. Omit it to leave it exactly as it is.
    summary
    optional
    string | nullThe longer summary (Markdown) shown to the reviewer above the tree — the sentence they read before any card. `null` clears it. Omit it to leave it exactly as it is.
  • update_plan_itemDeepen a proposal you appendedDestruktiv

    Fill in a proposal you appended — the deepen turn while the plan is being written, or, with `revision: true`, a rewrite of a card on a plan already in review, in place.

    PropertyTypeDescription
    planId
    required
    stringThe plan id `create_plan` returned.
    planItemId
    required
    stringThe proposal to deepen — one of the ids `add_plan_items` returned in `planItemIds`, in the order you sent them.
    title
    optional
    stringReplace the proposed title. Cannot be blanked — a proposal needs a title.
    kind
    optional
    string
    epic · story · task · bug · subtask
    Replace the proposed kind.
    descriptionMd
    optional
    stringnullMarkdown body — WHAT to do. Send `null` to clear it; omit to leave it as it is.
    explanationMd
    optional
    stringnullMarkdown body — WHY it matters. Send `null` to clear it; omit to leave it as it is.
    type
    optional
    string | null
    code · design · test · content · copy · translate · research · review · verification · decision · choice · deploy · manual · legal · chore
    Leaf work type. A CLOSED set: these fourteen members ARE the schema enum; `null` clears it.
    priority
    optional
    string | null
    lowest · low · medium · high · highest
    Priority; `null` clears it.
    executor
    optional
    string | null
    coding_agent · human
    WHO executes this leaf. Worth setting whenever you set `type`: approving a plan does NOT derive an executor from the type, so a proposal that never carried one materializes unassigned. `null` clears it.
    storyPoints
    optional
    numbernullAgile sizing, re-validated on the merged result exactly as at append; `null` clears it.
    estimateMinutes
    optional
    integer | nullEstimated minutes of work; `null` clears it.
    difficulty
    optional
    string | null
    trivial · low · medium · high
    How hard the work is to REASON about, not how big it is (that is `storyPoints` / `estimateMinutes`): "trivial", "low", "medium", "high", easiest first. Leaf kinds only (task / bug / subtask): a non-null value on an epic or story is refused with INVALID_PROPOSAL naming `difficulty`, never silently dropped. Judged on the MERGED kind. Send `null` to clear it; omit to leave it as it is.
    todos
    optional
    object[] | nullThe card’s ORDERED STEPS, written as its to-do list. ARRAY ORDER IS LIST ORDER — the sequence they are performed in — and approving the plan writes one real to-do row per element, none ticked. A `manual` card’s steps belong HERE, not only in the description: the reviewer reads the list they will tick before they approve it, and the created card carries it from birth. Leaf kinds only — a container’s steps are its children. REPLACES the list whole — a list has no sparse edit — so send the set you want; `[]` or `null` clears it, and omitting it leaves the proposal’s list alone.
    revision
    optional
    booleanSet true to edit a proposal on a plan you have ALREADY closed — a plan that is `planned` and in front of a reviewer. Without it such an edit is refused. The plan does NOT re-open: it is `planned` before, during and after, and the edit is recorded on its timeline with the harness and model that made it. This is how a card’s WORDS are corrected on a landed plan — the same card, same id and edges — rather than by withdrawing it and appending a copy. On a `generating` plan it is unnecessary and changes nothing. `approved` and `declined` stay frozen.
  • update_plan_proposalCorrect a proposal, including its structureDestruktiv

    Correct a proposal — including its parent, its dependency and supersedes edges, its obsolescence mark and note, and its whole repository axis (a repo, a row, a set, or a role) — even after the plan is in review; a corrected mark is re-checked, so setting one on an unfinished card is refused.

    PropertyTypeDescription
    planId
    required
    stringThe plan id `create_plan` returned.
    planItemId
    required
    stringThe proposal to correct — one of the ids `add_plan_items` returned in `planItemIds`, in the order you sent them.
    title
    optional
    stringReplace the proposed title. Cannot be blanked — a proposal needs a title.
    kind
    optional
    string
    epic · story · task · bug · subtask
    Replace the proposed kind.
    descriptionMd
    optional
    stringnullMarkdown body — WHAT to do. Send `null` to clear it; omit to leave it as it is.
    explanationMd
    optional
    stringnullMarkdown body — WHY it matters. Send `null` to clear it; omit to leave it as it is.
    type
    optional
    string | null
    code · design · test · content · copy · translate · research · review · verification · decision · choice · deploy · manual · legal · chore
    Leaf work type. A CLOSED set: these fourteen members ARE the schema enum; `null` clears it.
    priority
    optional
    string | null
    lowest · low · medium · high · highest
    Priority; `null` clears it.
    executor
    optional
    string | null
    coding_agent · human
    WHO executes this leaf. Worth setting whenever you set `type`: approving a plan does NOT derive an executor from the type, so a proposal that never carried one materializes unassigned. `null` clears it.
    storyPoints
    optional
    numbernullAgile sizing, re-validated on the merged result exactly as at append; `null` clears it.
    estimateMinutes
    optional
    integer | nullEstimated minutes of work; `null` clears it.
    difficulty
    optional
    string | null
    trivial · low · medium · high
    How hard the work is to REASON about, not how big it is (that is `storyPoints` / `estimateMinutes`): "trivial", "low", "medium", "high", easiest first. Leaf kinds only (task / bug / subtask): a non-null value on an epic or story is refused with INVALID_PROPOSAL naming `difficulty`, never silently dropped. Judged on the MERGED kind. Send `null` to clear it; omit to leave it as it is.
    todos
    optional
    object[] | nullThe card’s ORDERED STEPS, written as its to-do list. ARRAY ORDER IS LIST ORDER — the sequence they are performed in — and approving the plan writes one real to-do row per element, none ticked. A `manual` card’s steps belong HERE, not only in the description: the reviewer reads the list they will tick before they approve it, and the created card carries it from birth. Leaf kinds only — a container’s steps are its children. REPLACES the list whole — a list has no sparse edit — so send the set you want; `[]` or `null` clears it, and omitting it leaves the proposal’s list alone.
    parentRef
    optional
    stringnull`add` only: re-parent the proposal. A work-item KEY ("ACME-7"), a real work-item id, or a `planItem:<id>` ref naming another `add` on THIS plan; `folder:<folderId>` to file it into a folder of this project instead; `null` makes it top-level. Re-validated by the same checks the append runs, so a key or a ref naming nothing is refused here rather than at approve — and a ref to the proposal ITSELF is refused too.
    blockedByRefs
    optional
    string[]REPLACES the dependency edges wholesale — a list has no sparse edit, so send the set you want and `[]` to clear it. Same ref rules and same re-validation as `parentRef`.
    supersedesRefs
    optional
    string[]REPLACES an `add`’s supersedes set wholesale — send the set you want, `[]` to clear it. `add` only: the OLDER cards the created card REPLACES. Approve writes one `supersedes` link from the new card to each. Each entry is a work-item KEY ("ACME-7"), a real work-item id, or a `planItem:<id>` ref naming an `add` ALREADY on this plan (returned by an EARLIER call) — so a done card can be marked superseded by a card this plan creates. A key is resolved to its id here, and one that names nothing is refused `dangling` at this call. A `folder:<id>` ref, a ref listed twice, or the target itself is refused INVALID_PLAN_REF_GRAPH; so is an edge that closes a supersedes CYCLE (A replaces B replaces A). No level rule: any kind may supersede any kind. Refused on a `modify` (it spells its edges on the patch: `supersedesAdd` / `supersededByAdd`) and on a `remove`. This does NOT mark the older card — to mark it `outdated`, send a mark-only `modify` of it with `supersededByAdd: ["planItem:<this add>"]` in a LATER call. To change a `modify`’s supersedes edges, replace its `patch` instead.
    targetRepo
    optional
    stringnull`add` only: re-pin WHICH REPO this proposal ships in, validated against the project’s repository set (a repository connected to the workspace but not linked to the project is rejected); `null` unpins it.
    targetRepos
    optional
    string[]`add` only: REPLACE this proposal’s repository set with these ordered names; `[]` unpins it. ⚠️ The repository axis is REPLACED rather than merged — correcting one of `targetRepo` / `targetRepos` / `targetRepositories` CLEARS the other two, because they are one field in three spellings and a proposal carrying two would be a contradiction approve had to guess at.
    targetRepositories
    optional
    string[]`add` only: the same replacement, as the project’s repository ROW IDS. Clears the other two spellings, for the reason above.
    targetRepositoryRef
    optional
    stringnull`add` only: re-pin the SINGULAR ROW-ID half of the pin (Story MOTIR-2732 · MOTIR-3045, surfaced by MOTIR-4924) — the one spelling that names one of two rows sharing a role. `null` unpins it. Clears the other spellings, for the reason above.
    targetRepoRole
    optional
    stringnull`add` only: re-pin the PORTABLE half of the pin — a ROLE of the project’s repository set, validated against the closed role vocabulary rather than the project’s rows; `null` unpins it. This is the pin an ONBOARDING plan actually carries, because its repositories do not exist yet.
    subject
    optional
    stringnull`add` only: re-pin the SUBJECT coordinate — which rule packs an authoring pass composes for this leaf. An explicit `null` unpins it. Correctable here and NOT on the deepen turn, deliberately: a subject says where the card sits in the RULE CORPUS rather than what it says, so it is settled at the `lay` beside `type` and the repo pin. Re-validated by the same shape and container checks the append runs; membership is not checked here in either door.
    patch
    optional
    object | null`modify` only: REPLACES that proposal’s patch. This is the op no door could touch at all before — and the one that carries a dependency edit, so it is usually what a mistyped `planItem:` ref is sitting on. It is also how a `modify`’s MARK is corrected: the replacement patch’s `obsolescence`, `obsolescenceNoteMd` and four supersedes lists are re-checked exactly as the append checks them, including the finished-target rule.
  • withdraw_plan_proposalTake a proposal off a planDestruktiv

    Take one proposal off a plan, instead of asking a reviewer to decline the whole thing.

    PropertyTypeDescription
    planId
    required
    stringThe plan id `create_plan` returned.
    planItemId
    required
    stringThe proposal to take off the plan — one of the ids `add_plan_items` returned.

MCP-Server covers wiring an agent to the endpoint and the token it needs.