Studio Churn Risk Report
Generates a live, interactive churn risk dashboard for any MarianaTek studio using the connected MCP server.
Step 1: Identify the MCP server
Check which MarianaTek studio MCP is connected and available. Common ones include:
Cousteau / Cousteau Admin
Spin Unlimited
Ra Yoga
Zenergy
OneSweat
Use whichever studio MCP the user has connected and is asking about. If multiple are connected, ask the user which studio they want the report for.
Step 2: Pull live member data
Call studio_list_users (with page_size: 100 or more) on the appropriate MCP to get all members. Extract for each member:
id
full_name
completed_class_count
date_joined
archived_at (to filter out churned/archived members)
Filter to active members only (archived_at is null).
Step 3: Classify risk tiers
Use these definitions:
- Critical risk: 1–2 classes completed
- High risk: 3–5 classes completed
- Engaged: 6–20 classes completed
- Power users: 21+ classes completed
Compute:
- Total active members
- Count and % per tier
- Average classes per member
- At-risk count (critical + high risk combined)
Step 4: Render the report widget
Use visualize:read_me with modules ["chart", "data_viz"] then visualize:show_widget to render the report.
Report layout (match this exactly)
Metric cards row (4 cards):
- Total members
- Avg classes per member (1 decimal)
- At risk count (≤5 classes) — danger color
- Critical risk count (1–2 classes) — danger color
Two charts side by side:
- Left: Doughnut chart — 4 tiers, colors: Critical=#E24B4A, High=#EF9F27, Engaged=#97C459, Power=#1D9E75. Custom HTML legend above with counts and percentages.
- Right: Bar chart — member count by class bracket: [1–2, 3–5, 6–10, 11–20, 21–50, 51+]. Same color scheme: red for 1–2, amber for 3–5, blue for 6–20, teal for 21+.
At-risk members table (members with ≤5 classes):
- Columns: Name | Classes | Risk level
- Critical rows get
background: var(--color-background-danger)
- Risk badge: Critical = #E24B4A bg / #FCEBEB text, High = #EF9F27 bg / #412402 text
- Sort by classes ascending
Action buttons row:
- "Draft re-engagement email ↗" →
sendPrompt('Draft a re-engagement email for my at-risk members')
- "Download PDF" → client-side PDF using
window.print() with a print stylesheet that hides the buttons. Inject a <style> block @media print { .no-print { display: none !important; } body { -webkit-print-color-adjust: exact; } } and wrap buttons in <div class="no-print">. The download button calls window.print().
Chart.js config notes
- Load from:
https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.js
- Every canvas needs
role="img", aria-label, and fallback text
- Disable default legend:
plugins: { legend: { display: false } }
- Use
responsive: true, maintainAspectRatio: false
- Canvas wrapper:
position: relative; width: 100%; height: 220px
- All chart colors are hardcoded hex (canvas cannot resolve CSS variables)
Design system
- Metric cards:
background: var(--color-background-secondary), border-radius: var(--border-radius-md), padding 1rem
- Table:
border: 0.5px solid var(--color-border-tertiary), border-radius: var(--border-radius-lg)
- All text uses CSS variables for dark mode compatibility — never hardcode
color: #333 etc.
- Buttons: plain
<button> tags (pre-styled by the host)
- No emoji, no gradients, no drop shadows
- Sentence case everywhere
Step 5: Follow-up
After rendering, be ready to:
- Draft a re-engagement email if the user clicks the button or asks
- Drill into a specific member's profile
- Filter the list differently (e.g. "show only members who joined in the last 60 days")
- Re-run with updated data
1---2name: studio-churn-risk-report3description: Generates a live member churn risk report for a MarianaTek fitness studio using the connected MCP. Use this skill whenever the user asks for a churn report, member risk analysis, at-risk members, member engagement report, or wants to know which members might cancel or stop coming. Triggers on phrases like "churn report", "at-risk members", "member engagement", "who's not coming in", "members at risk", "re-engagement", or any request to analyze member attendance patterns. Always use this skill for these requests — do not attempt to generate the report from memory or without pulling live MCP data.4---56# Studio Churn Risk Report78Generates a live, interactive churn risk dashboard for any MarianaTek studio using the connected MCP server.910## Step 1: Identify the MCP server1112Check which MarianaTek studio MCP is connected and available. Common ones include:13- `Cousteau` / `Cousteau Admin`14- `Spin Unlimited`15- `Ra Yoga`16- `Zenergy`17- `OneSweat`1819Use whichever studio MCP the user has connected and is asking about. If multiple are connected, ask the user which studio they want the report for.2021## Step 2: Pull live member data2223Call `studio_list_users` (with `page_size: 100` or more) on the appropriate MCP to get all members. Extract for each member:24- `id`25- `full_name`26- `completed_class_count`27- `date_joined`28- `archived_at` (to filter out churned/archived members)2930Filter to active members only (`archived_at` is null).3132## Step 3: Classify risk tiers3334Use these definitions:35- **Critical risk**: 1–2 classes completed36- **High risk**: 3–5 classes completed37- **Engaged**: 6–20 classes completed38- **Power users**: 21+ classes completed3940Compute:41- Total active members42- Count and % per tier43- Average classes per member44- At-risk count (critical + high risk combined)4546## Step 4: Render the report widget4748Use `visualize:read_me` with modules `["chart", "data_viz"]` then `visualize:show_widget` to render the report.4950### Report layout (match this exactly)5152**Metric cards row** (4 cards):531. Total members542. Avg classes per member (1 decimal)553. At risk count (≤5 classes) — danger color564. Critical risk count (1–2 classes) — danger color5758**Two charts side by side**:59- Left: Doughnut chart — 4 tiers, colors: Critical=#E24B4A, High=#EF9F27, Engaged=#97C459, Power=#1D9E75. Custom HTML legend above with counts and percentages.60- Right: Bar chart — member count by class bracket: [1–2, 3–5, 6–10, 11–20, 21–50, 51+]. Same color scheme: red for 1–2, amber for 3–5, blue for 6–20, teal for 21+.6162**At-risk members table** (members with ≤5 classes):63- Columns: Name | Classes | Risk level64- Critical rows get `background: var(--color-background-danger)`65- Risk badge: Critical = #E24B4A bg / #FCEBEB text, High = #EF9F27 bg / #412402 text66- Sort by classes ascending6768**Action buttons row**:691. "Draft re-engagement email ↗" → `sendPrompt('Draft a re-engagement email for my at-risk members')`702. "Download PDF" → client-side PDF using `window.print()` with a print stylesheet that hides the buttons. Inject a `<style>` block `@media print { .no-print { display: none !important; } body { -webkit-print-color-adjust: exact; } }` and wrap buttons in `<div class="no-print">`. The download button calls `window.print()`.7172### Chart.js config notes73- Load from: `https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.js`74- Every canvas needs `role="img"`, `aria-label`, and fallback text75- Disable default legend: `plugins: { legend: { display: false } }`76- Use `responsive: true, maintainAspectRatio: false`77- Canvas wrapper: `position: relative; width: 100%; height: 220px`78- All chart colors are hardcoded hex (canvas cannot resolve CSS variables)7980### Design system81- Metric cards: `background: var(--color-background-secondary)`, `border-radius: var(--border-radius-md)`, padding 1rem82- Table: `border: 0.5px solid var(--color-border-tertiary)`, `border-radius: var(--border-radius-lg)`83- All text uses CSS variables for dark mode compatibility — never hardcode `color: #333` etc.84- Buttons: plain `<button>` tags (pre-styled by the host)85- No emoji, no gradients, no drop shadows86- Sentence case everywhere8788## Step 5: Follow-up8990After rendering, be ready to:91- Draft a re-engagement email if the user clicks the button or asks92- Drill into a specific member's profile93- Filter the list differently (e.g. "show only members who joined in the last 60 days")94- Re-run with updated data