--- name: forecast description: Build a forecast dashboard in monday — committed, best-case, and pipeline views by close month, rendered as real dashboard widgets. Use when someone says "build me a forecast", "show me Q2 pipeline", "Salesforce-style forecast", "forecast dashboard", "commit vs best-case", "what's our number this quarter", "how are we tracking to quota", "weighted pipeline", "deal rollup", "Clari-style", "pipeline by month", or "what's in commit". argument-hint: "[optional: board name or ID, e.g. 'Deals' or '12345678'; optionally add period, e.g. 'Q2 2026' or 'next 90 days']" user-invocable: true allowed-tools: [Read, mcp__monday_crm__get_user_context, mcp__monday_crm__list_workspaces, mcp__monday_crm__search, mcp__monday_crm__get_board_info, mcp__monday_crm__get_column_type_info, mcp__monday_crm__get_board_items_page, mcp__monday_crm__board_insights, mcp__monday_crm__create_dashboard, mcp__monday_crm__create_widget, mcp__monday_crm__create_doc, mcp__monday_crm__create_notification, mcp__monday_crm__create_column, mcp__monday_crm__change_item_column_values, mcp__monday_crm__list_users_and_teams, mcp__monday_crm__all_monday_api] --- # Forecast Dashboard Builds a native monday dashboard that renders the pipeline as a forecast — committed / best-case / pipeline / closed-won, grouped by stage × close month. Replaces the "export to CSV and pivot it" pattern that sales ops leaders do manually every Monday. Flow: **Trigger → Gather → Synthesize → Publish (α, default) → Share (β, opt-in) → Proactive extension (opt-in, hygiene fix)**. ## Input - Optional: board name / ID + forecast period (e.g., "Q2 2026", "next 90 days"). - Optional: pre-declared mode (Default / Silent / Proactive). ## Output - **α (default):** A native monday `create_dashboard` with widgets per bucket + URL. - **β (Share):** Viewer-permission grant to sales leader via `all_monday_api` + `create_notification`. - **Proactive extension:** Hygiene fix — if a non-closed deal is missing close date, `change_item_column_values` (with batched user confirm) to set a placeholder OR post a prompt update asking the owner to fill it. Missing-amount items are flagged in the dashboard description and a hygiene update is posted on the item, but the amount column itself is never written (forecast integrity rail). ## Knowledge - Bucket definitions: closed-won / committed / best-case / pipeline (§ Step 5). - Shared artifact conventions (see Shared patterns section below). ## Tools (MCP) - `get_user_context`, `list_workspaces`, `search` — board resolution. - `get_board_info`, `get_column_type_info` — schema + column types (stage/amount/close-date/forecast-category). - `get_board_items_page` — paginated pull. - `board_insights` — aggregate fallback. - `create_dashboard`, `create_widget` — α publish. - `create_doc` — fallback for non-admins (see Error handling). - `create_notification`, `list_users_and_teams` — β share. - `create_column` — add a forecast-category column only if required to render the dashboard. - `change_item_column_values` — proactive hygiene fix. - `all_monday_api` — escape hatch for dashboard permissions, idempotency GraphQL query, and doc updates. ## Cross-skill handoffs - **From daily-briefing:** If the briefing surfaces forecast-hygiene issues (missing close date or amount on >10% of deals), the user may jump here to build the structured view. - **To data-cleanup:** If >25% of deals are missing core forecast fields, suggest `/monday-crm:data-cleanup` before publishing. --- ## Step 0: Connector check **Goal:** Fail fast if the user has no monday MCP connection. 1. Try `get_user_context`. 2. If the tool is missing, returns auth-style error, or the user has no accessible workspace: - Print exactly: *"I don't see the monday connector active on this session. Install it from https://monday.com/mcp, then run this skill again."* - Stop. Do not proceed. 3. If connector works, cache `user.id` and `user.name` for artifact metadata. **PAUSE**: Do not call `create_dashboard`, `create_widget`, `create_column`, or `change_item_column_values` before Step 0 passes and the user has confirmed the publish step in Step 6. --- ## Step 1: Detect mode + confirm forecast period **Goal:** Know write-confirmation policy AND lock the forecast window. 1. Detect Default / Silent / Proactive per shared pattern. 2. If no period declared, ask the user: "Which period? (a) this quarter, (b) next 90 days, (c) custom." Store `period_start`, `period_end`. --- ## Step 2: Resolve the deals board (Gather) **Goal:** Land on one (or user-confirmed multi) board. Same resolution path as daily-briefing Step 2. Use `get_user_context` → `list_workspaces` → `search("deal")`. --- ## Step 3: Read board schema (Gather) **Goal:** Resolve columns by type — stage (`status`), amount (`numbers` with `$`), close date (`date` with "close"/"expected"), forecast category (`status` with commit/best-case/pipeline labels, if present). 1. `get_board_info(boardId)`. 2. `get_column_type_info` for any ambiguous column. 3. If no forecast-category column exists AND the user wants commit vs best-case split: prompt the user — "I can add a `Forecast Category` column (Commit / Best-case / Pipeline / Omit). OK?" Only create via `create_column` in Proactive mode or after explicit user approval. --- ## Step 4: Pull deal data (Gather) **Goal:** Paginated pull over the forecast window. `get_board_items_page` with `filters` = close_date in `[period_start, period_end]`. Paginate via `cursor` up to 2K items (same cap as daily-briefing). Same 429 / rate-limit handling. --- ## Step 5: Synthesize (Synthesize) **Goal:** Group deals into forecast buckets × close month. Buckets: - **Closed-won** — stage `is_done: true` (won label). - **Committed** — forecast category = Commit OR (probability ≥ 80% AND stage in late-funnel). - **Best-case** — forecast category = Best-case OR (probability in 50-79% AND stage in mid-funnel). - **Pipeline** — everything else active. **Empty-category guard:** If a forecast-category column exists but fewer than 20% of active deals have a non-empty value, surface this warning before synthesizing: > The Forecast Category column exists but 80%+ of deals haven't been categorized. I'll derive all buckets from probability + stage for now. Want to: (a) continue anyway, (b) run hygiene to prompt owners to fill it, or (c) remove the column from the forecast logic? Wait for user choice before proceeding. Group by close month within the period. Compute Σ amount per (bucket × month). --- ## Step 6: Publish α — build the dashboard (Publish) **Goal:** Produce a native monday dashboard with widgets per bucket, not a markdown brief. Core call pattern: 1. **Idempotency:** Before creating, query for an existing `Forecast — ` dashboard using `all_monday_api` with a GraphQL `dashboards` query (filtered by name where the API supports it), then check each result's `description` client-side for the `` comment. Note: `search` does not cover dashboard descriptions and must not be used for this check. If a matching dashboard is found, update widgets via that dashboard ID instead of duplicating. 2. `create_dashboard(workspaceId, name: "Forecast — ", description: "Generated by Claude · · ")`. 3. For each bucket × month: `create_widget(dashboardId, ...)` — see Widget call shapes below. 4. Return dashboard URL. Print it as the last line in chat. ### Widget call shapes Required fields for each widget type: **Number widget** (per-bucket total): ```json { "type": "numbers", "board_ids": [""], "column_ids": [""], "filter": { "rules": [{ "column_id": "", "compare_value": ["