From monday CRM
Produces a daily prioritized briefing over monday CRM data and publishes it as a monday artifact. Handles pipelines, contacts, accounts, leads, or no board.
How this skill is triggered — by the user, by Claude, or both
Slash command
/monday-crm:daily-briefing [optional: board name or ID, e.g. 'Deals', 'Contacts', or '12345678'][optional: board name or ID, e.g. 'Deals', 'Contacts', or '12345678']This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Produces a daily prioritized briefing over the user's monday CRM data and **publishes it as a monday artifact** — so the brief lives inside monday, not just in the chat.
Produces a daily prioritized briefing over the user's monday CRM data and publishes it as a monday artifact — so the brief lives inside monday, not just in the chat.
Works for any monday CRM setup: pipeline users get deal buckets and pipeline totals; contacts/accounts users get relationship health and follow-up queues; lead managers get inbound lead status. If the user has no monday CRM board at all, the skill runs in standalone mode — ask for context, produce a useful brief from what they tell you.
When monday CRM features are in use, the brief automatically gets richer:
| monday CRM feature | What it adds | MCP access |
|---|---|---|
| Notetaker | Recent meeting notes matched to open deals or contacts | get_notetaker_meetings |
| Activity log | Logged calls, emails, and meetings on deals/contacts (last 48h) | get_board_activity + get_updates |
| Tasks / follow-ups | Items with a date column = today across deals or contacts board | get_board_items_page with date filter |
| Calendar sync (Outlook/Google) | Today's CRM-linked meetings | Not yet in MCP — skipped; wired when available (see workset status.md) |
| Email sync (Gmail/Outlook) | Tracked email threads on deals/contacts | Not yet in MCP — skipped; logged emails accessible today via get_updates on contacts/deals |
monday CRM's calendar and email sync features exist in the product but are not fully exposed via the MCP connector yet. The skill attempts to reach them via
all_monday_apiraw GraphQL. If the data isn't there, it notes the gap in the brief and skips the section — it does not error out.
Flow: Connector check → Mode → Connector discovery → Board detection → Board type → Data pull → Synthesize → Publish → Share (opt-in) → Proactive (opt-in).
Morning Briefing — <weekday>, <Mon DD>. Body carries the Generated by Claude footer + an HTML comment <!-- claude-skill-id: daily-briefing --> for idempotency. Markdown brief printed in chat as a mirror.create_update on stalled records; create_notification for commitments due today.get_user_context — resolve user + favorite boards.list_workspaces — enumerate workspaces when search is ambiguous.search — find CRM boards by broad search terms.get_board_info — board schema + column IDs + labels.get_column_type_info — resolve columns by type when names aren't English.get_board_items_page — pull active records, recently closed, recent activity.board_insights — aggregate fallback when >200 items.create_update — publish α to pinned item; proactive nudges on stalled records.create_doc — publish α as a doc when no pinned item exists.create_notification — β share; proactive alert for commitments due today.list_users_and_teams — resolve recipient for β share.all_monday_api — escape hatch for doc updates / metadata lookups not in wrapped tools./monday-crm:forecast-dashboard./monday-crm:board-diagnosis.Goal: Fail fast if the user has no monday MCP connection.
mcp__monday__get_user_context.user.id and user.name.PAUSE: do not write any
create_*call before Step 6, and never before Step 0 passes.
Goal: Know write behavior and output preferences before doing anything else.
create_* or change_* call in chat before executing.If no mode declared, assume Default. Trigger: morning briefing silent / morning briefing proactive / mode: proactive in project instructions.
Hard safety rail regardless of mode: no deletes, no amount-column writes, no cross-workspace moves. Stage, owner, last-touch, and source column edits are allowed when bundled in a batched-confirm plan (Default) or session-level approval (Proactive).
Read from project instructions or per-run prompt. All fields are optional — defaults apply when absent.
Verbosity (default: full)
full — all sections, per-deal detail, pipeline totalsquick — headline numbers + top 3 action items only (fits in ~20 lines)tldr — single paragraph: one priority, one number, one actionTrigger phrases: quick brief / quick morning briefing → quick; tldr / tldr my day → tldr.
Sections (default: all on)
Set per-run with natural language ("skip yesterday's movements", "only show what needs attention") or in project instructions:
output:
sections:
pipeline_totals: true # "Pipeline at a glance"
yesterday_movements: true # won/lost since last run
meeting_today: true # deals with a meeting today (requires notetaker or calendar)
tasks_today: true # tasks/follow-ups due today
needs_action: true # slipping, stale, follow-up buckets
on_track: true # hot deals
activity_summary: true # logged calls/emails/notes count
new_this_week: false # new deals added (off by default — low urgency)
data_hygiene: true # missing fields, unowned items
Any section with no items is automatically omitted regardless of config (don't print empty headers).
Style (default: bullets)
bullets — markdown bullets and headers (default, renders well in monday docs and chat)tables — key data in markdown tables (better for scanning many deals)prose — short paragraph per section (better for sharing / pasting into email)Trigger: morning briefing table format → tables; morning briefing prose → prose.
Destination (default: monday+chat)
monday+chat — publish artifact to monday AND mirror in chatmonday — publish to monday only, no chat mirrorchat — chat only, no monday artifact (useful for quick checks without cluttering monday)doc — force a new monday doc even if a "My Morning" pinned item existsTrigger: morning briefing chat only → chat; morning briefing doc → doc.
Config precedence: per-run prompt overrides project instructions, which overrides defaults. A per-run phrase like "quick brief" applies to this run only — it does not change stored config.
Goal: Know which monday-native data sources are live before pulling CRM data. Run in parallel with Step 2.
Try each source silently — don't stop if one fails:
Notetaker meetings — call get_notetaker_meetings. If it returns results, cache them. If it errors or returns empty, mark notetaker: false.
Calendar sync — not yet available via monday MCP. Mark calendar: false. Skip. Will be wired when monday exposes calendar_events in the MCP connector (tracked in workset status.md).
Email sync — not yet available via monday MCP. Mark email: false. Skip. Will be wired when monday exposes crm_emails in the MCP connector (tracked in workset status.md). Note: logged emails stored as item updates on contacts/deals are accessible today via get_updates — those are handled in Step 5d.
Tasks board — search get_user_context → relevantBoards for a board named tasks|to-do|actions|follow-up. If found, mark tasks_board: <boardId>. If not found, skip — tasks will be inferred from deal/contact items with date columns = today.
None of these failing should block the rest of the skill. Calendar and email sync are product features not yet fully exposed in the MCP — the attempt is best-effort. Notetaker and tasks are available today.
Goal: Find the user's CRM board(s), or confirm there are none and fall back to standalone.
Broad search — cast the net wide:
If the user passed a board via argument:
boardId directly.mcp__monday__search(searchType: "BOARD", searchTerm: <arg>). One match → use it. Multiple → AskUserQuestion.If no argument, scan get_user_context → relevantBoards + favorites for names matching any of:
deal|deals|opportunity|opportunities|pipeline|salescontact|contacts|account|accounts|client|clients|customer|customerslead|leads|prospect|prospects|inboundpartner|partners|renewal|renewals|relationshipIf no matches in context, run search with searchTerm: "crm" then "contacts" then "deals". Collect all candidates.
If still zero matches → Standalone fallback (see Step 2c below). Do not stop the skill.
If multiple candidates of the same type (e.g., two pipeline boards):
updated_at on its items — this is the board the user is actively working in. Note the selection in the brief's Data hygiene section: "Briefing on [Board Name]. To brief a different board, pass its name as an argument."updated_at is the same day or indeterminate: AskUserQuestion with board names + "all of them" option.If candidates are of different types (e.g., one pipeline + one contacts board): run both paths and combine into one brief — no disambiguation question needed.
If the user explicitly picks "all": run Steps 3–7 per board and publish one combined α artifact.
Goal: Tailor the data pull and synthesis to what the user actually has.
After resolving the board, call get_board_info and classify as one of:
| Type | Signals |
|---|---|
pipeline | status column with is_done: true labels (Won) + numbers column with $ unit (value) |
leads | status column without is_done: true (no Won state) + lead-sounding labels (e.g. "New", "Contacted", "Qualified", "Disqualified") |
contacts | Majority text / email / phone columns; few or no numbers columns; no Won/Lost pattern |
accounts | Mix of text, numbers (revenue/ARR), status columns; company-centric item names |
general | CRM board that doesn't fit above — treat like accounts |
Cache the detected boardType for Steps 3–6.
If a user has both a pipeline board and a contacts/accounts board, run both paths and combine into one brief under separate sections.
Goal: Still produce a useful briefing even without a monday board connected.
Run this path if Step 2 found zero boards OR the user says "I don't have a CRM set up yet."
Ask the user two questions (one AskUserQuestion call, both together):
Work with whatever they provide. Produce a briefing using the Standalone template (§ Step 6c). Skip Steps 3–5 and Steps 7–9 (nothing to publish). Print the brief in chat only.
Goal: Resolve column IDs by type — global teams have non-English column titles.
get_board_info(boardId). Cache columns.Pipeline columns:
| Concept | Type | Title hint | Fallback |
|---|---|---|---|
| Stage | status | stage, status | first status with is_done labels |
| Owner | people | owner, rep, person | first people column |
| Value | numbers | value, amount, revenue, size | first numbers with $ unit |
| Close probability | numbers | probability, % | first numbers with % unit |
| Expected close date | date | close, expected, target | first date-type column matching |
| Last interaction | date | interaction, activity, touch, contacted | second date-type column |
| Forecast value | formula | forecast, weighted | optional; computed from value × prob if absent |
Contacts/accounts columns (additional):
| Concept | Type | Title hint |
|---|---|---|
| Company | text | company, account, organization |
email | ||
| Phone | phone | phone |
| Last contacted | date | last contacted, last touch, last interaction |
| Next follow-up | date | follow-up, next contact, next step |
| Owner | people | owner, rep, assigned |
| Status | status | status, stage, health |
| Tags | tags | tags, segment, type |
get_column_type_info.Goal: Distinguish closed records from active — without hardcoding English.
Skip this step for contacts, accounts, general board types.
From the stage column's settings.labels:
is_done: true.lost|closed lost|cerrado perdido|verloren|perdu.is_done: true label exists, ask the user which label means "won".Cache label index values.
Goal: Get the items needed to build the brief. Adapt the queries to the board type.
Three passes:
Pass A — Active: get_board_items_page with stage not_any_of [won_idx, lost_idx], limit 200.
Pass B — Recent closures: stage any_of [won_idx, lost_idx], ordered by updated_at desc, limit 50; in-memory filter to items with updated_at within last 24h.
Pass C — Recent activity: reuse Pass A; sort by updated_at desc; last 24h.
Volume edges:
10K items: stop at 2,000, surface sampling note.
board_insights fallback if >200 active items for aggregate-only view.Two passes:
Pass A — All active contacts/accounts: get_board_items_page, no status filter (include all non-archived), limit 200. Include: owner, last-contacted date, next-follow-up date, status, company.
Pass B — Recent activity: sort Pass A by updated_at desc; last 48h.
Two passes:
Pass A — Open leads: get_board_items_page, filter out terminal labels (e.g., "Disqualified", "Converted"), limit 200.
Pass B — Recent additions: sort by created_at desc, last 48h.
This is the primary way to get logged emails, calls, and activities from monday CRM today. When users log a call, send an email (via monday email sync), or add a note on a contact or deal, it's stored as an update thread on that item. get_updates surfaces all of it.
For each resolved board:
get_board_activity(boardId, from: <48h ago>) — structural changes: stage moves, owner assignments, column edits. Tells you what changed on which items.get_updates(boardId, limit: 100) — update threads: logged calls, tracked emails, meeting notes, manual notes added by reps. This is the activity log.If either call returns a permission error (403 or similar): note in the brief's Data hygiene section — "Activity log unavailable — the MCP connector lacks read access to this board's activity feed. A board admin can grant it under Board Settings → Permissions → View board." Do not stop or retry; proceed without activity data.
Classify each update body by content signals:
For the contacts board specifically: this is where email/activity history lives. Pull updates for all contacts that appear in your deals or that you own — not the full board. Filter by updated_at within last 48h to stay relevant.
Cache per item: {itemId, activityType, summary (first 100 chars), timestamp, author}[]. Group by deal/contact for synthesis.
If notetaker: true from Step 1b: the cached get_notetaker_meetings results contain recent meeting recordings/notes with associated items.
For each notetaker entry:
matched_meeting_notes[] for synthesis.Unmatched meetings (no CRM item linked): surface separately in the brief under "Meetings not linked to a deal" — they're an upsell opportunity.
If tasks_board was found in Step 1b: call get_board_items_page on that board filtered by due date = today.
If no tasks board: scan Pass A results (deals/contacts) for items where any date column = today that isn't the close date (treat as a follow-up or task date).
Cache as tasks_today[] with item name, assigned owner, linked board.
Not available via monday MCP today. Skip. When monday exposes calendar_events on the connector: pull today's events, cross-reference with open deals/contacts by crm_item link or attendee domain match, cache as crm_meetings_today[] for synthesis Step 6a. See workset status.md for tracking.
Not available via monday MCP today. Skip. Logged emails stored as item updates on contacts/deals are covered by Step 5d (get_updates). When monday exposes crm_emails on the connector: pull unread emails + awaiting_reply threads, cross-reference with CRM items, surface in the brief under "Email priorities". See workset status.md for tracking.
429 → exponential backoff 3x (1s, 2s, 4s). On third failure: "monday is rate-limiting right now. Retry in 60 seconds, or narrow to fewer boards." Stop.
Goal: Rank items by what needs action today.
| Bucket | Criteria |
|---|---|
| Meeting today | deal has a crm_meetings_today entry — always surface, regardless of other signals |
| Task due today | deal appears in tasks_today — surface with task description |
| Commit-today | close_date = today AND stage ≠ Won/Lost |
| Slipping | close_date in past AND stage ≠ Won/Lost |
| Stale | last_interaction > 14d ago AND stage in non-closed |
| Follow-up | last_interaction > 7d ago AND probability ≥ 50% |
| Hot | probability ≥ 70% AND last_interaction ≤ 7d AND close_date ≤ 30d |
| New | created within last 7d AND stage = earliest-index label |
Priority order: Meeting today > Task due today > Commit-today > Slipping > Stale > Follow-up > Hot > New.
A deal can appear in multiple buckets — display in the highest-priority one only, but annotate lower-priority signals inline (e.g., a Stale deal that also has a meeting today → show under "Meeting today" with a 🔴 stale flag).
Totals: active pipeline Σ value; forecast Σ (value × prob/100); closing this week count + Σ value; yesterday wins Σ value; yesterday losses count.
Section header counts must match body item counts exactly. Count the items in each bucket after applying verbosity limits, then write ### Slipping (N) where N is the actual number of lines that follow. Never use a pre-limit count in the header.
Activity summary: count of logged calls, emails, meetings, and notes in the last 24h across all active deals. Surface as a one-liner in the brief (e.g., "5 activities logged yesterday — 2 calls, 2 emails, 1 note").
| Bucket | Criteria |
|---|---|
| Overdue follow-up | next_follow_up date in past |
| Going cold | last_contacted > 21d ago AND no upcoming follow-up |
| Follow-up today | next_follow_up = today |
| Recently active | updated_at within last 24h |
| New this week | created_at within last 7d |
Priority order: Overdue > Follow-up today > Going cold > Recently active > New.
No pipeline totals for contacts boards. Instead surface: total contacts, unowned contacts (%), contacts with no follow-up date set.
| Bucket | Criteria |
|---|---|
| Hot leads | status in early/qualified stages AND created within last 7d |
| Unassigned | owner column empty |
| Stale | created > 14d ago AND no status change in 7d |
| Recent additions | created_at within last 48h |
Surface: total open leads, unassigned count, conversion rate (if terminal labels detected).
Prioritize from user-provided input:
Goal: Put the brief inside monday. Skip for standalone mode (nothing to publish to).
Respect the destination config from Step 1:
chat → skip this step entirely; print to chat only.doc → skip "My Morning" search; go directly to create_doc.monday or monday+chat (default) → follow steps below.search(searchType: "ITEM", searchTerm: "My Morning"). Filter results to boards the user owns or is a member of (to avoid false matches on shared workspaces). If exactly one match → create_update on that item. If multiple → take the one in the user's personal workspace (from get_user_context → personal_workspace_id). If none → proceed to step 2.create_doc in personal workspace with title Morning Briefing — <weekday>, <Mon DD>, <YYYY>.— v2). Never duplicate.Before assembling the brief body, apply the config from Step 1:
tldr verbosity: replace the full template with: one sentence on top priority, one pipeline number, one suggested action. Skip all sections.quick verbosity: include only pipeline_totals + needs_action (top 2 items max per bucket, 1-line each). Skip yesterday_movements, on_track, new_this_week, activity_summary, data_hygiene. Hard cap: 25 lines total including headers and footer. (~20 is achievable when fewer buckets are populated; top 2 per bucket keeps within cap even when all three action buckets are full.)full verbosity (default): all sections per config.tables style: render deal lists as markdown tables (| Deal | Stage | Value | Alert |) instead of bullets.prose style: write each section as 1–2 sentences, no headers. Use plain paragraph breaks.If a section is configured
onbut has zero items, omit it silently — don't print "(none)".
Pipeline template:
# CRM Morning Briefing — <weekday>, <Mon DD>
<!-- claude-skill-id: daily-briefing -->
## Pipeline at a glance
- Active pipeline: $<total>K across <N> deals
- Forecast: $<forecast>K (weighted)
- Closing this week: <N> deals, $<value>K
## Yesterday's movements
- Won: <deal> ($<value>K, <owner>)
- Lost: <deal> ($<value>K, <owner>)
## Needs you today
### Closing today (<N>)
- <deal> — <stage>, $<value>K, owner <name>, last touch <X days ago>
### Slipping (<N>)
- <deal> — <stage>, $<value>K, expected <date> (<X> days overdue), owner <name>
### Going cold (<N>)
- <deal> — <stage>, no touch in <X> days, owner <name>
### Follow-up (<N>)
- <deal> — <stage>, <probability>%, last touch <X days ago>
## On track
- <deal> — <stage>, <probability>%, closing in <X> days
## Data hygiene
- <N> deals missing owner · <N> missing close date · <N> missing amount
---
Generated by Claude · <ISO timestamp> · run `/monday-crm:daily-briefing` to refresh.
Contacts / accounts template:
# CRM Morning Briefing — <weekday>, <Mon DD>
<!-- claude-skill-id: daily-briefing -->
## Relationships at a glance
- <N> contacts/accounts total · <N> owned by you · <N> unowned
## Needs you today
### Overdue follow-ups (<N>)
- <name> (<company>) — follow-up was due <date>, owner <name>
### Follow up today (<N>)
- <name> (<company>) — scheduled for today, last touched <X days ago>
### Going cold (<N>)
- <name> (<company>) — no contact in <X> days, no follow-up scheduled
## Recently active
- <name> — updated <X hours ago>
## New this week
- <name> (<company>) — added <date>
## Data hygiene
- <N> contacts missing owner · <N> with no follow-up date set
- (Run `/monday-crm:board-diagnosis` for a full audit.)
---
Generated by Claude · <ISO timestamp> · run `/monday-crm:daily-briefing` to refresh.
Leads template:
# CRM Morning Briefing — <weekday>, <Mon DD>
<!-- claude-skill-id: daily-briefing -->
## Leads at a glance
- <N> open leads · <N> unassigned · <N> added this week
## Needs you today
### Unassigned leads (<N>)
- <lead name> — <stage>, added <date>
### Hot leads (<N>)
- <lead name> — <stage>, <X> days old, owner <name>
### Going stale (<N>)
- <lead name> — <stage>, no activity in <X> days
## Recent additions
- <lead name> — added <X hours ago>, source <source>
## Data hygiene
- <N> leads unassigned · <N> with no status change in 7+ days
- (Run `/monday-crm:board-diagnosis` for a full audit.)
---
Generated by Claude · <ISO timestamp> · run `/monday-crm:daily-briefing` to refresh.
Standalone template (chat-only, no artifact):
# Morning Brief — <weekday>, <Mon DD>
## #1 Priority
**[Most important thing from what you told me]**
[Why it matters]
## Today's meetings
- [Time / Company / What's at stake]
## Needs attention
- [Item 1 — why]
- [Item 2 — why]
## Suggested next actions
1. [Action] — [why now]
2. [Action] — [why now]
3. [Action] — [why now]
Print before any create_*: "I'll publish this as <target>. OK to post? (yes / no / show first)." Silent and Proactive modes skip this.
monday+chat (default): print the brief in chat as a mirror + artifact URL on last line: Posted: <url>.monday: print one-liner only: Posted: <url> — no full mirror.chat: print the full brief in chat. No artifact URL.doc: same as monday+chat.create_update → create_doc → print-only with banner "Couldn't publish to monday (permission error). Brief below."Runs only if user explicitly asked ("share with my manager", "post to the team", or Proactive mode selected Share).
list_users_and_teams → resolve recipient. Default to declared manager if present; else AskUserQuestion with top-5 linked teammates.create_notification({ userId, itemId: <artifact>, text: "Morning briefing for <Mon DD>" }).create_update on a team-rollup board (resolve by search / AskUserQuestion — don't assume a fixed name). Same footer + skill-id-comment convention.Runs only if mode = Proactive AND session decision was "approve all" or "review each".
For each item in Stale / Going cold bucket:
create_update(itemId, "*Claude nudge:* No activity in <X> days. What's the next step?").For each item in Commit-today / Overdue follow-up bucket:
create_notification({ userId: <owner>, itemId, text: "Action due today on <name>" })."Review each" flow: print a one-line proposal per item before writing. yes → execute; no → skip; stop → halt.
Guard rails:
Proactive actions — <date>) with a single prompt.Print: Published Morning Briefing — <date>. <N> items scanned, <N> actions posted, <N> pending.
If any write failed mid-run: list written items in chat for manual cleanup. Do not attempt compensating deletes.
Generated by Claude · <timestamp> footer + <!-- claude-skill-id: daily-briefing --> HTML comment.| Failure | Behavior |
|---|---|
| Connector not installed | Step 0 stops; print install link |
| No CRM board found | Standalone fallback (Step 2c) — don't stop |
| Board >10K items | Cap at 2K most-recent, flag sampling |
| MCP tool error (retryable) | Backoff 3x; skip that strand; surface partial brief |
| Same-day artifact exists | Update in place |
| User halts mid-session | List written items in chat; no compensating deletes |
| 429 rate limit | Backoff 3x, then stop with retry message |
| Publish perms failure | Degrade to doc → print-only |
| Multiple CRM boards | AskUserQuestion with "all of them" option |
| Non-English columns | Resolve by type via get_column_type_info |
| Proactive writes >20 | Batch into one review-list doc |
Generated by Claude footer + <!-- claude-skill-id: daily-briefing --> comment.npx claudepluginhub mondaycom/mcp --plugin monday-crmBuilds a CRM workspace from scratch in monday.com based on a business description. Automatically creates boards, columns, and pipeline stages.
Generates prioritized daily sales briefings from meetings, deals, priorities, or connected calendar, CRM, and email for action plans.
Generates weekly pipeline health digest for active Linear deals, categorizing by progress, stale status, risks, and new additions; compiles action items, stage summaries, and posts to Slack.