Skip to content

work

Project management: projects, epics, deliveries, tasks, business units, and member placement against the work schema.

Endpointhttps://work.mcp.devfellowship.com/mcp
Tools34
Backing datawork schema (projects, epics, deliveries, tasks, business units, placements).
ToolDescription
create_projectCreate a new project.
delete_projectDelete a project. This will fail if the project has associated epics.
get_projectGet a specific project by ID with its epics.
list_projectsList all projects with optional filters.
update_projectUpdate an existing project.
ToolDescription
create_epicCreate a new epic. ⚠️ An epic cannot be shown on a plan — the plans-app renders bound tasks only. Bind the epic’s tasks instead.
delete_epicDelete an epic. This will fail if the epic has associated deliveries or tasks.
get_epicGet a specific epic by ID with its deliveries and tasks.
list_epicsList all epics with optional filters.
update_epicUpdate an existing epic.
ToolDescription
create_deliveryCreate a new delivery.
delete_deliveryDelete a delivery.
get_deliveryGet a specific delivery by ID with its epic and tasks.
list_deliveriesList all deliveries with optional filters.
update_deliveryUpdate an existing delivery.
ToolDescription
create_taskCreate a new task. Requires a context package (why/what) and a stage_id (spec / design / execution / review / decision / qa) — a task without a stage is invisible on the board. If it belongs to a plan, also call set_plan_tasks on the plans MCP — see the callout above.
delete_taskDelete a task.
get_taskGet a specific task by ID with its epic and delivery.
list_tasksList all tasks with optional filters.
update_taskUpdate an existing task.
ToolDescription
create_business_unitCreate a new business unit. Requires finance/admin/owner role.
delete_business_unitDelete a business unit by ID. Requires finance/admin/owner role.
get_business_unitGet a specific business unit by ID. Requires finance/admin/owner role.
list_business_unitsList all business units with optional filters. Requires finance/admin/owner role.
update_business_unitUpdate an existing business unit. Requires finance/admin/owner role.
ToolDescription
create_placementRecord a DFL fellow placement (job/freelance/internal) in work.placements. Resolve the member_id first via lookup_member on the learn endpoint.
create_member_label_aliasMap a raw speaker/label string to a member by upserting into work.member_label_aliases.
ToolDescription
merge_meetingsDedup a duplicate recurring-meeting cluster by merging a skeleton meeting into a canonical meeting, then removing the skeleton. Lossless on duplicate-date collisions: it never drops a transcription-bearing occurrence in favor of an empty one. For a date both meetings share, it compares transcripts on both sides — if the canonical occurrence is empty but the skeleton one carries a real transcript, it re-parents the skeleton occurrence onto the canonical and deletes the empty canonical duplicate (the real transcript survives). If both carry transcripts it reports a conflicts entry, keeps both, and does not remove the skeleton row (skeleton_meeting_removed: false, manual review). Empty skeleton duplicates of an existing canonical date are dropped; skeleton occurrences on a new date are re-parented. Other meeting_id child rows (participants/concepts/expertise/tools/underlines) are re-parented onto the canonical, guarding the work.meeting_participants unique constraint. The skeleton row is removed only when there are zero unresolved conflicts. Transcriptions live per-occurrence so nothing is concatenated and the canonical survives. It also preserves the work.meetings.template field: if the canonical is null/"default" and the skeleton carries a non-default template (e.g. "weekly_leaders"), the canonical is updated to the skeleton’s template (carry the more-specific value forward; never downgrade). Pass dry_run: true first to preview the change without writing.
set_meeting_recurrence_timeSet the time-of-day window (recurrence_start_time / recurrence_end_time) on a single recurring meeting series in work.meetings, so its recurring occurrences render at the right hour on the /meetings time-grid. Times are 24h wall-clock "HH:MM" or "HH:MM:SS" (Postgres time). The meeting must already be a recurring series (is_recurring = true); recurrence_day_of_week is set separately. Returns the updated row.
set_meeting_templateSet the UI template (work.meetings.template) on a single meeting. The template selects which structured-underline UI the dfl-learn /meetings view renders — the weekly-leaders structured form is gated on template = "weekly_leaders". Allowed values: "default" | "weekly_leaders" (mirrors the dfl-learn UnderlineTemplate enum); unknown values are rejected. Returns the updated row. Primary use: restore a meeting’s template after a dedup-merge collapsed it to "default".
ToolDescription
list_meeting_seriesRead-only discovery of recurring series parents (work.meetings with is_recurring = true), so dedup targets can be found without psql. Filters: created_after / created_before (ISO-8601), title_contains, fireflies_calendar_id_contains, limit. Each result carries id, title, fireflies_calendar_id, meeting_date, created_at plus occurrence accounting (occurrence_count, occurrences_with_transcript, occurrences_with_transcript_id); include_occurrences: true adds the per-occurrence rows (id, date, status, has_transcript, fireflies_transcript_id). Transcript text is never returned — it is tens/hundreds of KB per occurrence. Sorted by created_at.
remove_meeting_seriesRemove one recurring series parent, promoting its occurrences to standalone (“avulsa”) meetings first so the cascade can never eat a transcript. occurrence_policy: promote_real_discard_empty (default — promote occurrences carrying transcript text or a Fireflies transcript id, delete the empty materializer placeholders), promote_all, or require_empty (pure safety mode). Guards, all of which abort rather than guess: occurrences with transcript text but no fireflies_transcript_id (unverifiable); occurrences whose transcript id already exists on a meetings row (skipped, not re-inserted — the partial unique uq_meetings_fireflies_transcript_id, which also makes the tool idempotent); rows in meeting_participants / meeting_concepts / meeting_expertise / meeting_tools / meeting_transcript_segments / meeting_underlines referencing the parent or its occurrences (use merge_meetings, which knows how to re-parent them); and a post-promotion assert that every surviving occurrence has a standalone counterpart before anything is deleted. Promoted rows get is_recurring: false, fireflies_calendar_id: null (deliberately detached), the parent’s title, and a meeting_date rebuilt from the occurrence date plus the parent’s time-of-day. Refuses a non-recurring meeting unless allow_non_recurring: true. Returns counts (total_occurrences / promoted / discarded / already_present, which must balance), the created standalone ids, and n8n_webhook_inserts.
promote_occurrence_to_standalonePromote one work.meeting_occurrences row to a standalone meeting and detach/delete the occurrence — the generic primitive underneath remove_meeting_series. Optional title_override; keep_occurrence: true creates the standalone but leaves the occurrence in place (copy-then-review, and the escape hatch for an occurrence whose transcript has no id or that still has participant/underline rows attached). Same unique/transcript/cascade guards; insert-and-confirm happens before any delete.

Read-only. What one member did in the last N days, per source, with a daily text ready to paste. Mirrors the Weekly updates page of dfl-learn (/weekly-updates).

ToolDescription
get_weekly_updatesmember_id? (default: you), days 1–14 (Brasília calendar days, today included). Sections: tasks moved to done / dev_completed (work.tasks.status_timestamps), tasks in progress, merged PRs (review_request.review_requests.merged_at, by created_by), Core Daily lines (resolved per meeting: segment attribution, then the top alias, then the exact name; any ambiguity leaves the line out), plans whose status changed (plans app, with your own session). Returns unavailable[] and truncated[] per source and daily_text in the Bom dia / Ontem / Hoje / No blockers format, one line per item, with no PR numbers, repos, task identifiers or links. Everything runs on your JWT; no service role.