* docs(PBI-12 T-54): voeg sprint-tools toe aan mcp-integration.md
Documenteert mcp__scrum4me__create_sprint en mcp__scrum4me__update_sprint
onder de Authoring-sectie, met verwijzing naar plan-to-pbi-flow.md voor
de werkwijze.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(PBI-12 T-55): promote plan-to-pbi-flow.md naar active
- frontmatter status: draft → active
- ⚠️-tooling-banner verwijderd; tools live sinds adbea3f in scrum4me-mcp
- korte note die naar mcp-integration.md verwijst voor tool-reference
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(CLAUDE.md): /init improvements (scripts, proxy hardstop, versies)
- Stack-tabel: exacte versies Next.js 16.2, React 19.2, Tailwind v4, Prisma v7.8
- Hardstop bullet voor proxy.ts (géén middleware.ts, demo-write blokkering)
- MCP-sectie: bewuste duplicatie van lib/job-config.ts ↔ scrum4me-mcp toegelicht
- Verificatie-sectie: npm scripts-tabel (dev/test/seed/create-admin/docs/diagrams)
+ Vitest exclude + server-only mock note
- Orientatie-tabel: verwijzing toegevoegd naar docs/runbooks/plan-to-pbi-flow.md
- frontmatter last_updated: 2026-05-11
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(PBI-12): implementatieplan voor sprint MCP-tools
Plan-file voor de twee tools (create_sprint + update_sprint) die de
sprint-lifecycle uit plan-to-pbi-flow.md ondersteunen. Beslissingen:
- Eén generieke update_sprint (geen losse close/fail/archive tools)
- Géén state-machine validatie (resubmit-mechanisme zit elders)
- Auto-end_date bij CLOSED/FAILED/ARCHIVED
- Cron + create_story sprint-param uit scope (apart later)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
126 lines
8.5 KiB
Markdown
126 lines
8.5 KiB
Markdown
---
|
|
title: "MCP Integration — Scrum4Me Tools"
|
|
status: active
|
|
audience: [ai-agent]
|
|
language: nl
|
|
last_updated: 2026-05-08
|
|
when_to_read: "When using MCP tools to interact with the Scrum4Me backlog."
|
|
---
|
|
|
|
# MCP-integratie
|
|
|
|
Scrum4Me heeft een eigen MCP-server in repo [`madhura68/scrum4me-mcp`](https://github.com/madhura68/scrum4me-mcp) die de REST-API als native tools voor Claude Code aanbiedt. Schema's worden gedeeld via een git submodule (`vendor/scrum4me`), niet gedupliceerd.
|
|
|
|
## Tools beschikbaar in Claude Code (18)
|
|
|
|
**Read / context:**
|
|
- `mcp__scrum4me__health` — service + DB ping
|
|
- `mcp__scrum4me__list_products` — producten waar de tokengebruiker toegang tot heeft
|
|
- `mcp__scrum4me__get_claude_context` — bundled product / actieve sprint (`status='OPEN'`) / next story (met tasks) / open ideas
|
|
|
|
**Authoring (PBI/Story/Task aanmaken):**
|
|
- `mcp__scrum4me__create_pbi` — `{ product_id, title, description?, priority, sort_order? }`; auto sort_order = last+1 binnen prio-groep
|
|
- `mcp__scrum4me__create_story` — `{ pbi_id, title, description?, acceptance_criteria?, priority, sort_order? }`; product_id afgeleid uit PBI; status=OPEN
|
|
- `mcp__scrum4me__create_task` — `{ story_id, title, description?, implementation_plan?, priority, sort_order? }`; sprint_id geërfd van story; status=TO_DO
|
|
|
|
**Sprint-lifecycle (PBI-12):**
|
|
- `mcp__scrum4me__create_sprint` — `{ product_id, code?, sprint_goal, start_date? }`; status start altijd op `OPEN`; code auto-gegenereerd als `S-{YYYY-MM-DD}-{N}` per product per dag als niet meegegeven; géén reuse-check op bestaande OPEN-sprints
|
|
- `mcp__scrum4me__update_sprint` — `{ sprint_id, status?, sprint_goal?, start_date?, end_date? }`; minimaal één veld vereist; **géén state-machine validatie** (last-write-wins, het resubmit/heropen-pad zit elders); auto-`end_date=vandaag` bij status → `CLOSED`/`FAILED`/`ARCHIVED` zonder expliciete end_date
|
|
|
|
> Wanneer en hoe deze sprint-tools in de plan-flow gebruikt worden: zie [docs/runbooks/plan-to-pbi-flow.md](./plan-to-pbi-flow.md).
|
|
|
|
> Idea-aanmaak loopt niet via MCP maar via de UI of `POST /api/ideas`. De voormalige `create_todo`-tool is verwijderd; idea-mutaties gaan via de Idea-tools onder *Idea-laag (M12)* hieronder.
|
|
|
|
**Task / story writes:**
|
|
- `mcp__scrum4me__update_task_status`, `mcp__scrum4me__update_task_plan`
|
|
- `mcp__scrum4me__log_implementation`, `mcp__scrum4me__log_test_result`, `mcp__scrum4me__log_commit`
|
|
|
|
**Vraag-antwoord-kanaal (M11):**
|
|
- `mcp__scrum4me__ask_user_question` — post een vraag over een story; optionele `wait_seconds` (max 600) polt voor het antwoord
|
|
- `mcp__scrum4me__get_question_answer` — huidige status + antwoord (voor latere session-pickup)
|
|
- `mcp__scrum4me__list_open_questions` — eigen vragen, max 50, recente eerst
|
|
- `mcp__scrum4me__cancel_question` — asker-only annulering van een eigen open vraag
|
|
|
|
**Job queue — agent worker mode (M13):**
|
|
- `mcp__scrum4me__wait_for_job` — blokkeert ≤600s, claimt atomisch een QUEUED-job via FOR UPDATE SKIP LOCKED. **Sinds M12** retourneert de payload een `kind`-discriminator:
|
|
- `kind: 'TASK_IMPLEMENTATION'` (default) — payload met `implementation_plan`, `story`, `pbi`, `sprint`, `repo_url`
|
|
- `kind: 'IDEA_GRILL'` of `'IDEA_MAKE_PLAN'` — payload met `idea`, `product`, `repo_url`, en `prompt_text` (de embedded prompt uit `lib/idea-prompts/`)
|
|
Stale CLAIMED-jobs (>30min) worden eerst terug naar QUEUED gezet. Lege queue na block-time = klaar.
|
|
- `mcp__scrum4me__update_job_status` — agent rapporteert `running|done|failed` + optionele branch/summary/error; triggert automatisch SSE-event. Bij `failed` voor `IDEA_GRILL`/`IDEA_MAKE_PLAN` wordt de idea-status automatisch op `GRILL_FAILED` resp. `PLAN_FAILED` gezet. Auth: Bearer-token moet matchen `claimed_by_token_id`. Optionele token-velden: `model_id` (string), `input_tokens`, `output_tokens`, `cache_read_tokens`, `cache_write_tokens` (alle non-negative int) — worden opgeslagen op de ClaudeJob-rij bij done/failed.
|
|
|
|
**Idea-jobs (M12) — agent gedrag per kind:**
|
|
|
|
| Kind | Werkwijze | Eind-call |
|
|
|---|---|---|
|
|
| `IDEA_GRILL` | Lees `prompt_text` (embedded grill-prompt) + `idea.grill_md` als startpunt; itereer met `ask_user_question(idea_id=...)`/`get_question_answer`; log onderweg `log_idea_decision`; eindig met `update_idea_grill_md(markdown)` | `update_job_status('done')` |
|
|
| `IDEA_MAKE_PLAN` | Lees `prompt_text` (embedded make-plan-prompt) + `idea.grill_md` + repo-context. **Stel GEEN vragen** — single-pass output. Bouw plan in strict yaml-frontmatter format en eindig met `update_idea_plan_md(markdown)`. Server-side parser kan parse-fail → `PLAN_FAILED` | `update_job_status('done')` |
|
|
|
|
**MCP-tools — Idea-laag (M12):**
|
|
- `mcp__scrum4me__get_idea_context(idea_id)` — `{ idea, product, repo_url, grill_md_so_far, open_questions, prompt_text }`
|
|
- `mcp__scrum4me__update_idea_grill_md(idea_id, markdown)` — schrijft veld; status → `GRILLED`; logt `IdeaLog{GRILL_RESULT}`
|
|
- `mcp__scrum4me__update_idea_plan_md(idea_id, markdown)` — server-side `parsePlanMd`; ok → `PLAN_READY` + `IdeaLog{PLAN_RESULT}`; parse-fail → `PLAN_FAILED` + `IdeaLog{JOB_EVENT, errors}`
|
|
- `mcp__scrum4me__log_idea_decision(idea_id, type, content, metadata?)` — `type ∈ {DECISION, NOTE}`
|
|
- `mcp__scrum4me__ask_user_question` — geüpgrade contract: exact één van `story_id` óf `idea_id` (xor); idea-vragen zijn user-private (geen productAccessFilter).
|
|
|
|
## Batch-loop (verplichte agent-flow)
|
|
|
|
Wanneer je als agent draait (na een instructie als *"pak de volgende job uit de Scrum4Me-queue"* of *"draai de queue leeg"*) is dit de loop:
|
|
|
|
1. `wait_for_job` aanroepen.
|
|
2. Switch op `kind`:
|
|
- `TASK_IMPLEMENTATION`: voer uit volgens het meegegeven `implementation_plan` (zoals altijd — branch, code, commit, push, verify_task_against_plan).
|
|
- `IDEA_GRILL`: laad `prompt_text` als gids; gebruik `ask_user_question` / `get_question_answer` voor de Q&A-loop; eindig met `update_idea_grill_md`.
|
|
- `IDEA_MAKE_PLAN`: laad `prompt_text` + `idea.grill_md`; **stel geen vragen**; produceer strict yaml-frontmatter; eindig met `update_idea_plan_md`.
|
|
3. `update_job_status('done'|'failed')` aanroepen.
|
|
4. **Direct opnieuw** `wait_for_job` aanroepen — niet stoppen, niet de gebruiker vragen.
|
|
5. Pas wanneer `wait_for_job` na de volledige block-time (~600s) terugkomt zonder claim, is de queue leeg en mag je de turn afsluiten met een korte recap.
|
|
|
|
Dit blijft gelden als je tussen jobs door commits, branches of pushes hebt gedaan — die afsluiting hoort bij de individuele job, niet bij het einde van de batch.
|
|
|
|
## Pre-flight quota-check (M13)
|
|
|
|
Vóór elke `wait_for_job`-aanroep doet de worker een pre-flight quota-check
|
|
om te voorkomen dat-ie 600 s blokkeert terwijl Anthropic-quota toch op
|
|
0 staat. Loop:
|
|
|
|
1. `mcp__scrum4me__get_worker_settings()` → `{ min_quota_pct }`
|
|
2. `bash bin/worker-quota-probe.sh` → JSON `{ pct, reset_at_iso, ... }`
|
|
3. `mcp__scrum4me__worker_heartbeat({ last_quota_pct: pct, last_quota_check_at })`
|
|
— server emit een SSE-event zodat NavBar realtime de stand-by-badge
|
|
kan tonen
|
|
4. **Als `pct < min_quota_pct`**: log "stand-by, wachten tot
|
|
`reset_at_iso`", sleep tot reset (cap op 1 uur), spring naar stap 2
|
|
5. **Anders**: ga door met `wait_for_job`
|
|
|
|
Pseudo-bash:
|
|
|
|
```bash
|
|
QUOTA_JSON=$(/opt/agent/bin/worker-quota-probe.sh)
|
|
PCT=$(echo "$QUOTA_JSON" | jq -r '.pct')
|
|
RESET=$(echo "$QUOTA_JSON" | jq -r '.reset_at_iso')
|
|
|
|
# Stuur naar server (best-effort; failure niet-fataal)
|
|
mcp_call worker_heartbeat "{\"last_quota_pct\": $PCT}"
|
|
|
|
if [[ "$PCT" -lt "$MIN_PCT" ]]; then
|
|
log "stand-by until $RESET (pct=$PCT < min=$MIN_PCT)"
|
|
sleep_until "$RESET"
|
|
continue
|
|
fi
|
|
```
|
|
|
|
**Beperking**: de probe kost ~1 outputtoken per check. 12 checks/uur =
|
|
12 tokens/uur overhead — verwaarloosbaar. De `min_quota_pct`-setting
|
|
staat per default op 20% — bij vrije Pro/Max-plans typisch ruim genoeg
|
|
om dagelijks werk niet te verstoren.
|
|
|
|
**Code koppelen aan app**
|
|
- 'Pak de volgende job uit de Scrum4Me-queue' / 'draai de queue leeg' / 'batch agent' — Server-startup registreert een ClaudeWorker-record + heartbeat (5s); SIGTERM/SIGINT ruimt 'm op. UI in NavBar telt actieve workers via `last_seen_at < now() - 15s`.
|
|
|
|
## Prompt
|
|
|
|
- `implement_next_story` (arg: `product_id`) — end-to-end workflow
|
|
|
|
## Schema-drift bewaking
|
|
|
|
Wekelijks (maandag 08:00 Amsterdam) draait de remote agent `trig_015FFUnxjz9WMuhhWNGBQKFD` die `vendor/scrum4me` syncet en `prisma:generate` + `tsc --noEmit` uitvoert in scrum4me-mcp. Als die agent drift rapporteert, hoort dat **vóór** een Scrum4Me-PR met schema-wijziging gemerged kan worden — anders breekt de MCP-server stilletjes op runtime.
|