From monday CRM
Audits a Monday CRM board for data quality and fixes missing fields, bad phone formats, missing emails, unowned deals. Runs a health check report or performs bulk cleanup.
How this skill is triggered — by the user, by Claude, or both
Slash command
/monday-crm:data-cleanup [optional: board name or ID][optional: board name or ID]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
Two jobs in one skill for the recurring "my CRM is messy" pain (Sidekick's #1 negative-sentiment JTBD):
Two jobs in one skill for the recurring "my CRM is messy" pain (Sidekick's #1 negative-sentiment JTBD):
Flow (report): Trigger → Gather → Score (5 strands) → Publish diagnosis doc → offer to fix. Flow (fix): Trigger → Audit → User picks gaps → Plan writes → Execute (bounded, idempotent) → Summary.
Hygiene fix — <Mon DD> doc lists every change with Generated by Claude footer + <!-- claude-skill-id: data-cleanup -->.get_user_context, list_workspaces, search, get_board_info, get_column_type_info, get_board_items_page, board_insights — Gather.list_users_and_teams — enumerate users for bulk-assign owner step.change_item_column_values — the core write. Loop with bounded concurrency.create_doc / create_update — publish summary + before/after snapshot.all_monday_api — escape hatch for column types not exposed by change_item_column_values. For country columns, use: change_multiple_column_values with column_values: {"<country_col_id>": {"countryCode": "<ISO2>", "countryName": "<name>"}}. Do not freeform the mutation type — only this shape is supported for country columns.Goal: Fail fast if the user has no monday MCP connection — no partial writes, no guessing.
mcp__monday__get_user_context.user.id + user.name for artifact metadata.Hard safety rail regardless of mode: no deletes, no amount-column writes, no cross-workspace moves, no normalization on columns the user didn't pick. Stage / owner / source / last-touch edits ARE allowed when the user explicitly selected that gap type at Step 4 — data-cleanup is the canonical place for board-wide column rewrites that other skills point users at.
Also detect report vs. fix intent:
Goal: Land on a single boardId before reading any data.
boardId directly; string → mcp__monday__search with searchType: "BOARD". One match → use it; multiple → AskUserQuestion.get_user_context → scan relevantBoards + favorites for names matching deals|opportunities|pipeline|leads|sales|contacts|accounts. One candidate → use it; multiple → AskUserQuestion; zero → list_workspaces → search. Still zero → stop with "I don't see a CRM-shaped board in your workspaces. Tell me the board name or ID, or run /monday-crm:workspace-builder to create one."Goal: Produce a scored structural audit as a doc — no writes. Run only when the user asked for a report/health check (see Step 1 intent). Otherwise skip to Step 3.
Pull board schema (get_board_info, get_column_type_info), items (get_board_items_page, up to 2K most-recent), aggregate stats (board_insights — known ~9% baseline error rate; on failure skip that strand and note it), and activity (get_board_activity, or derive staleness from item updated_at). Then score five strands:
all_monday_api; if scope unavailable, skip with note).Scoring (each strand 0–100, floor 0): Missing data 100 − (15·P0 + 8·P1 + 3·P2) · Stalled 100 − 15/group · Drift 100 − 8/column · Automations 100 − 20/missing stage automation · Structure 100 − 10/issue.
Overall = weighted avg: Missing 40% + Stalled 20% + Drift 15% + Automations 15% + Structure 10%.
Severity: P0 = fill-rate <50% on required fields, stall >90d, or no stage automation (blocks forecast/reporting). P1 = fill-rate 50–75%, stall 30–90d, column <5% populated. P2 = structural/minor.
Publish: create_doc titled Board Health Check — <board> — <Mon DD>, body carries Generated by Claude · <ISO> + <!-- claude-skill-id: data-cleanup -->. Sections: overall score + 5-strand breakdown, P0 fixes ([P0] <issue> → <fix>), P1/P2 batched, automation recommendations, column-archive list. Healthy-board shortcut: score ≥90 and zero P0/P1 → skip the doc, print the score + inline P2 notes.
Then offer to fix: "Want me to fix the fixable gaps now? I can normalize phone/email/country and bulk-set owner/source/stage within a scope you pick." → yes routes to Step 3; no stops here. Report path writes nothing.
Goal: Compute a gap report grouped by fix-type, with a concrete count per type.
Pull all items via get_board_items_page (paginated up to 5000, then sample with disclosure). For each item, check:
| Gap type | Audit rule | Fixable here? |
|---|---|---|
| Missing email | email column empty AND contact name present AND company resolvable (see note below) | ✅ (heuristic guess from company domain — flagged with Source = guessed) |
| Missing phone | phone column empty | ❌ (no source — flag only) |
| Phone format | Phone present but no country code, or contains letters / >2 separators | ✅ (E.164 normalization) |
| Country code missing | country column empty AND phone has parseable country code OR email domain has CCTLD | ✅ |
| Email case | Mixed-case ([email protected]) | ✅ (lowercase) |
| Stale last-touch | date last-touch >90d AND stage active | ✅ (set to "today" only if user picks; never overwrites a more-recent date) |
| Owner missing | people owner empty AND stage active | ✅ (bulk-assign within a user-picked group/scope) |
| Stage drift | items in non-canonical groups; user explicitly wants normalization | ✅ (bulk-set within user-picked scope) |
| Amount missing | numbers value empty AND stage past "qualifying" | ❌ (flag only — forecast integrity rail) |
| Source missing | status source column empty | ✅ (bulk-set within user-picked scope) |
"Company resolvable" definition for email guessing: look for (a) a text or email column containing a domain (@ or .), (b) a board_relation column linking to an accounts board, or (c) an item name matching First Last @ CompanyName. If none found, mark the item as not guessable.
Resolve columns by type, not English name (same rule as daily-briefing). Skip gap types where the matching column doesn't exist.
Produce the audit summary in chat:
## Audit — <board name>
**Items scanned:** N
**Gaps found:**
- ✅ Fixable (column normalization): <N> phone formats · <N> mixed-case emails · <N> missing country codes · <N> guessable missing emails
- ✅ Fixable (bulk-set within picked scope): <N> missing owners · <N> stale last-touch · <N> missing sources · <N> stage drift
- ⚠️ Flag-only: <N> missing phones (no source) · <N> missing amounts (forecast integrity rail)
Pick which fixable gaps to run, or "all". Flag-only items list in the summary doc — no writes.
First, ask whether to create a before/after snapshot: "Want a snapshot doc so you can see exactly what changed and roll back individual cells if something looks off? (yes / no)"
Then AskUserQuestion, multiSelect:
Scope picker for bulk-set options: if the user picked multiple bulk-set options (owner / source / stage / last-touch), ask once: "Should the same scope (group / filter) apply to all of them, or do you want to set each separately?" One question beats four. If "same for all" → ask scope once and apply it across all bulk-set options. If "separately" → run a scope sub-prompt per option.
For bulk-set options, use list_users_and_teams to present available owners/teams when the target owner needs to be selected.
If user picks "Guess missing emails", surface a strong warning: "Email guessing uses a <first>.<last>@<companydomain> pattern. Accuracy varies widely — works best for B2B companies with standard email formats, unreliable for personal domains or non-Western name conventions. Only recommended for Leads boards where invalid sends are tolerable. Continue?"
Hard rule: no fix runs without an explicit Step 4 selection (and a scope-picker confirm for bulk-set options). Empty selection → stop with summary-only.
Goal: Bounded, idempotent loop. Every write is reversible.
For each picked gap type, build a write plan: list of (itemId, columnId, oldValue, newValue, reason).
+ characters.+ AND country column is populated → prepend dial code per country.+ AND country empty AND phone starts with a known country prefix (e.g., 1 for US, 44 for UK) → prepend +.value.toLowerCase(). Only write if changed.all_monday_api with {"countryCode": "<ISO2>", "countryName": "<name>"} shape..uk / .de / .fr etc. and country empty → infer.<firstname>.<lastname>@<domain> lowercase. Add a Source = guessed status flag on the item so the user can filter and verify later. If a source/status column is missing, prompt the user once to add one — never write the email without a verifiability flag.change_item_column_values. Never extend beyond the picked scope.change_item_column_values, batched by item (one call per item updates multiple columns at once). Concurrency: 5 in flight max to avoid rate limits.Updated 50/500 cells. Continuing...Compute oldValue == newValue per cell — never write a no-op (avoids audit-log noise).
create_doc (idempotent — search same-day docs by title + skill-id comment, update in place if found), title Hygiene fix — <Mon DD>. Body:
# Hygiene fix — <board name> · <Mon DD>
<!-- claude-skill-id: data-cleanup -->
## Writes executed (<N>)
| Item | Column | Old → New | Scope / reason |
|---|---|---|---|
| ... | ... | ... | ... |
## Skipped (<N>)
| Item | Column | Reason |
|---|---|---|
## Flag-only (no writes)
- N items missing phone (no source — manual entry required)
- N items missing amount (forecast integrity rail — review manually)
## Undo
Every write here is reversible. The "Old" column above shows the prior value. To revert: find the row in monday and copy the Old value back in manually.
---
Generated by Claude · <ISO timestamp>
Optional β: create_update on a "snapshot" item with the pre-fix state of every touched item, for 30-day rollback window. Only runs if user opted in at Step 4.
One-line chat summary: Cleaned <N> cells across <M> items on <board>. <K> skipped. Doc: <url>.
If any failures: <N> failed (rate limits / permissions). Re-run to retry — already-fixed cells are idempotent.
Generated by Claude · <ISO timestamp> footer + <!-- claude-skill-id: data-cleanup --> in summary/snapshot doc bodies.oldValue == newValue.data-cleanup — new installs write <!-- claude-skill-id: data-cleanup -->. Any artifacts created by the prior board-diagnosis or bulk-data-hygiene skills carry their old markers and will not be found by this skill's idempotency check — treat them as separate artifacts.Board Diagnosis — Sales Pipeline — Jun 15
<!-- claude-skill-id: data-cleanup -->
**Score: 62 / 100**
| Strand | Score | Detail |
|---|---|---|
| Missing data | 55 | 12 deals missing Owner (fill-rate 78%) |
| Stalled groups | 40 | 8 deals stalled >30d in "Discovery" |
| Column drift | 85 | "Legacy Status" column — 0% fill, candidate for archive |
| Automations | 60 | No stage-move automations on this board |
| Structure | 90 | Board structure looks sound |
**P0 fixes (2)**
- [P0] Owner blank on 12 active deals → batch-assign in bulk-data-hygiene
- [P0] 8 deals stalled in "Discovery" >30d → review + advance or lose
**P1 fixes (1)**
- [P1] "Legacy Status" column — 0% fill over 90d → archive via Board Settings
**Automation recommendations**
- Add status-change → email-owner automation for stage moves
---
Generated by Claude · 2026-06-15T09:00:00Z
# Hygiene fix — Sales Pipeline · Jun 15
<!-- claude-skill-id: data-cleanup -->
## Writes executed (3)
| Item | Column | Old → New | Scope / reason |
|---|---|---|---|
| Acme Corp — Q3 expansion | Phone | +1-555-123-4567 | +15551234567 | E.164 normalize |
| Beta Industries — pilot | Email | [email protected] | [email protected] | lowercase |
| Gamma Ltd — renewal | Country | (empty) | GB (United Kingdom) | from email CCTLD .co.uk |
## Skipped (0)
## Flag-only (no writes)
- 12 items missing Owner (no source — select scope then re-run to bulk-assign)
- 2 items missing Amount (forecast integrity rail — review manually)
## Undo
Every write here is reversible. The "Old" column above shows the prior value.
---
Generated by Claude · 2026-06-15T09:00:00Z
Chat one-liner:
Cleaned 3 cells across 3 items on Sales Pipeline. 0 skipped. Doc: [url].
| Failure | Behavior |
|---|---|
| Connector missing | Step 0 stops; print install link. |
| No board found | Step 2 stops; suggest workspace-builder. |
| Empty selection at Step 4 | Skip writes; publish summary doc with audit only. |
| 0 fixable gaps | Print "Board's already clean — N flag-only items in summary doc." |
| 429 rate limit | Backoff 3x; halt on third with partial summary. |
| Per-item permission error | Skip, log, continue. |
| Column type changed mid-run | Skip that column on that item, continue. |
| User halt | Keep writes done; emit partial summary with last-written item ID. |
| Email-guess accuracy concern | Strong warning at Step 4; Source = guessed flag on every guessed write. |
<!-- claude-skill-id: data-cleanup --> + Generated by Claude footer.Source = guessed flag (or were withheld if no flag column existed).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.
Generate a phased implementation plan from a HubSpot audit report. Creates prioritized, sequenced cleanup processes with effort estimates, dependencies, and automation feasibility. Use after running /hubspot-audit.
Sets up Airtable-based sales ops and CRM workflows: pipeline, account/renewal management, deal desk, RFP tracking, partner CRM, forecasting, and vertical CRMs. Augments Salesforce/HubSpot or builds Airtable-as-CRM with AI-native GTM stacks.