Skip to content

plans

Search, read, author, and triage plans on plans.devfellowship.com — the DFL planning system (plans, ADRs/decision records, and the questions/DTQ surface). This MCP wraps the same REST backend the web UI and the read-plan/search-plans/publish-plan skills use, so there is one backend and one visibility policy.

Endpointhttps://plans.mcp.devfellowship.com/mcp
Tools29
Backing dataThe plans REST API (plans.devfellowship.com/api) — plans, versions, ADRs, questions.
ToolDescription
search_plansHybrid semantic + keyword search over plans (and optionally ADRs). Results are visibility-filtered to what you can read.
read_planRead a plan’s full markdown body + metadata by slug (optionally a specific version). Returns not-found for plans you can’t read.
list_plansList plans with optional filters (status, source, tag, has_children, has_pending_questions). Returns only readable plans.
list_plan_tasksList the work tasks bound to a plan — its execution checklist, the read half of set_plan_tasks. Open tasks only by default (done + no_longer_needed hidden); pass include_finished: true for the whole set. The summary always counts every bound task, so you get “27 open of 33” plus a breakdown by status and by stage. Rows carry identifier, status, stage name, points, priority, owner, epic and acceptance criteria, read from work.tasks under your RLS. Sorted by stage → priority → identifier.
list_plans_by_activityList the plans with activity in a day window — the same rule as the calendar Day board (/calendar?view=day). Activity = the plan row (create, publish, status) plus every related entity (versions, comments, questions and answers, ADRs, child plans, bound tasks and content); the day is a calendar day in tz (default America/Sao_Paulo). Window: date (default today) or from + to (inclusive, max 62 days). mode: activity_on_day (default — any event in the window) or last_activity_on_day (the plan’s last event is in the window: “updated for the last time yesterday”). Filters: owner (me, a user id, an e-mail, or a name such as tainan; a name that matches two people is refused), status (comma list), limit (1–200, default 50). Each row: last activity, the window’s events, bound task counts by status, open and blocking questions, and whether the latest body has a ## Verification section. The start of a daily sweep (skill plans-day-sweep).
ToolDescription
create_planCreate a new plan (or upsert by slug). Owned by you; visibility defaults to shared. Requires a member+ identity.
publish_planPublish (or re-publish) a plan body, creating a new version. Upserts by slug. Requires a member+ identity.
patch_statusTransition a plan’s lifecycle status (draft → fired → executing → done / archived). Gated transitions are blocked while blocking questions are unanswered.
set_linksReplace a plan’s first-class sidebar links (Miro/Figma/GitHub/Epic/docs/… — separate from the markdown body). Replaces the whole list; owner-only; kind auto-detected from the URL. Pass [] to clear.
set_ownerReassign plans.owner to a canonical Supabase auth uid — by explicit slug list (targeted, repairs a legacy non-uuid owner) or for rows whose owner is NULL. plans.owner must be the auth uid: the readability predicate matches owner = auth.uid()::text, so a non-uuid owner makes a personal plan unreadable by its own owner. Superadmin only.
set_plan_tasksBind DevFellowship work tasks (work.tasks) to a plan — the plan’s execution checklist, rendered in the plans-app right sidebar with each task’s status and a done/total counter. Replaces the task list but preserves every other sidebar link. Owner or admin (a checklist is execution state, not sharing). Pass [] to unbind all.
ToolDescription
list_plan_commentsList the comments on a plan — id, version, selection_text, body, created_by, created_at and metadata. Optional version filter. Read-only.
delete_plan_commentDelete one comment by slug + comment_id. The API allows the comment author or an admin. Find the id with list_plan_comments.
create_plan_commentCreate a comment on a plan — the same plans.plan_comments annotation the web UI writes with select-to-comment. Required: slug, body. Optional: selection_text (the anchor; defaults to (plan) for a plan-wide comment), selection_start, selection_end, version, and metadata. created_by is resolved from your session and is not a settable field; metadata is optional JSON write attribution (max 8 KiB) — for example the requesting human and the channel when a bot writes the comment. Requires a member+ identity.

A plan can embed an artifact that lives in another DFL app — a diagram from diagrams.devfellowship.com, a document from documents.devfellowship.com, an image from the media bucket — instead of merely linking it. The plan body holds an External Entity Reference (EER): a token that points at the artifact and nothing else.

{{dfl-entity:<type>:<locator>}}
{{dfl-entity:<type>:<locator>|mode=live;caption=Arquitetura;rev=<uuid|iso8601>}}
{{dfl-diagram:<uuid>}} ← legacy alias for {{dfl-entity:diagram:<uuid>}}

type is diagram, document or image. The locator is a UUID for diagram and document; for image it is a media id or an https:// URL. Options after the | are k=v pairs separated by ; — mode (live, the default, or pinned), caption, rev.

ToolDescription
search_entitiesDiscovery. Find a diagram/document/image across the fleet and get its locator — the only way to obtain the UUID that attach_entity needs, since those artifacts live in other apps. Optional query (omit for most-recently-updated), type, and limit (default 20, max 50). Set include_latest_revision to also resolve each diagram hit’s newest revision id — the rev that pinning requires (at most 10 per call, one extra request each). Scoped to what you can see.
list_plan_entitiesList the entities a plan references, with each one’s type, locator, mode and caption. Derived by parsing the plan body, so it is always in sync; returns pointers, not resolved content. Read-only — never creates a version.
attach_entityInsert an EER token into a plan body without republishing the whole body. Takes slug, type, locator, plus optional mode, rev (the revision to pin a diagram to — see below), caption, and anchor (the text of an existing ## Heading to append under; defaults to an ## Entidades section at the end). Reports anchor_found: false when that heading did not exist and the token went to ## Entidades instead. Idempotent. Owner-gated.
detach_entityRemove a plan’s reference to one entity (slug, type, locator). Deletes the pointer only — the diagram/document/image itself is untouched. Idempotent. Owner-gated.
ToolDescription
list_discord_channelsList the Discord channels the DevFellowship bot can see, grouped by category, with client-facing ones tagged. The only valid source of a channel_id. Optional query filter and refresh to bypass the backend’s 60s cache.
set_plan_discord_channelBind a plan to one Discord channel, so every comment on it is announced there with a link back — or unbind with channel_id: null. Owner-only. Requires confirm_client_exposure: true when the target is client-facing or the plan is personal.
ToolDescription
list_adrsList ADRs for a single plan (visibility-gated) or globally with filters (tag, decided_by).
get_adrGet a single ADR by plan slug + decision number (or id). Visibility-gated via the parent plan.
ToolDescription
list_questionsTwo modes. With slug: one plan’s questions, grouped by round, with options and answers. Without slug: the cross-plan query over every readable plan. Filters: status (pending|answered|deferred|withdrawn|all, default pending), blocking, include_finished_plans, include_snoozed.
get_questionResolve ONE question by its UUID — no slug needed. Applies none of the inbox filters, so it finds answered/deferred/withdrawn questions and questions on done or archived plans. Returns the question with its plan_slug, plan_title, options and answer history.
update_questionEdit only question_text/context on the same question UUID. An empty context clears it. Rejects other fields. The plan editor check applies; status, options and answers remain intact.
post_questionCreate a structured question on a plan (DTQ). Set blocks_execution to gate the plan’s fire/execute transitions. Requires a member+ identity.
answer_questionRecord an answer to a plan question. Select option letters (["A"], or ["A","B"] when multi-select). To answer with free text that rejects every offered option, send the reserved letter ["OTHER"] and put the answer in freeform_notes — that records the question as answered, exactly like a letter does. [] with no notes is a reset back to pending, and [] with notes is rejected. The result states the status the server read back, so a reset is never reported as an answer.
withdraw_questionRetire an obsolete question (set status to withdrawn). Safe + idempotent: only OPEN (pending/deferred) questions are withdrawn; answered/already-withdrawn are left intact.
list_global_questionsThe cross-plan inbox, each item annotated with its plan slug + title (use for dedup). Same data as list_questions with no slug, and takes the same filters; defaults to OPEN (pending, non-snoozed) questions on unfinished plans.