Help us improve
Share bugs, ideas, or general feedback.
From cms-cultivator
Generates client-facing project heartbeat/status update messages for Kanopi projects by pulling activity from Teamwork and Fathom, then drafting in a consistent voice and format.
npx claudepluginhub kanopi/claude-toolbox --plugin cms-cultivatorHow this skill is triggered — by the user, by Claude, or both
Slash command
/cms-cultivator:project-heartbeatThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Generate a polished, client-facing Teamwork project update message by pulling recent
Aggregates context from Teamwork, Gmail, Slack, and Fathom to produce a structured briefing with talking points, ticket progress, and next steps for client check-ins.
Generates structured stakeholder updates with TL;DR headlines, progress trends, risks, and clear asks for status reports and executive summaries.
Provides scannable structures, honest framing, and warm recognition for team status updates, progress reports, and stakeholder communications.
Share bugs, ideas, or general feedback.
Generate a polished, client-facing Teamwork project update message by pulling recent activity from Teamwork and Fathom, then drafting it in Andrew's established voice and format.
If the conversation is happening inside a named Claude Project, infer the project from that context and confirm with the user before proceeding:
"I'll draft a heartbeat for [Project Name] — is that right?"
If the project is ambiguous or not obvious, ask directly:
"Which Teamwork project should I pull the heartbeat for?"
Once confirmed, look up the project in Teamwork to get its project_id.
⚠️ Critical: Heartbeat updates are posted as replies to a single long-running message thread, not as separate messages. The parent message may have been created months ago — its date is irrelevant. You must look at the replies, not the parent.
Using the Teamwork MCP:
list_messages to find the project's heartbeat/update message thread (typically titled "Project Update" or similar).list_message_replies with that message ID to fetch all replies.createdAt descending and taking the first result.createdAt of that most recent reply.Do not use the parent message's createdAt under any circumstances. The parent is just the thread container — the actual updates live in the replies.
Before moving to Step 3, confirm the window with the user:
"The last heartbeat reply was posted on [createdAt of most recent reply]. I'll pull activity from then through today ([TODAY]). Does that look right?"
Wait for confirmation before proceeding.
createdAt of the most recent reply in the heartbeat threadIf the message thread has no replies at all, fall back to the parent message's createdAt and note this is effectively the first update since the thread was opened.
Use Teamwork MCP tools for all Teamwork data (projects, tasks, messages). Use Fathom MCP tools for all meeting data.
Use the Teamwork MCP to pull all tasks completed within the reporting window for the project. Group them loosely by theme or tasklist (e.g. Discovery, Technical, UX, Content). Focus on tasks that would be meaningful to a client — skip purely internal admin tasks.
Use the Teamwork MCP to pull project messages from the reporting window. Scan for:
Use the Fathom MCP to search for meetings associated with this project during the reporting window. From each meeting, extract:
Use the Slack MCP to find and read the project's Slack channel. The channel name is typically
just the client name (e.g. #smalley for the Smalley project, #acme for an Acme project).
slack_search_channels to find the channel by the client/project name if the channel ID isn't already known.slack_read_channel to read messages within the reporting window. Filter to messages
that fall between the reporting window start date and today.If no matching channel is found, skip this step silently and proceed with the other sources.
If a Statement of Work or project brief has been added to this Claude Project as context, use it to:
Budget data is not pulled automatically — leave a clear placeholder in the draft:
[BUDGET TABLE — Please fill in manually:
Reporting Period: Thru [DATE]
Total Hours Used: [X]
Table: Item | Hours Allocated | Hours Used | Hours Remaining | Notes]
Use the structure and tone from the reference examples below. Write in Andrew's voice: warm, professional, client-focused, concise. Avoid internal jargon. Do not mention specific team member names unless they were already shared with the client.
@[Client contacts]
[Opening paragraph — 2–4 sentences]
Warm opener referencing where the project is at. High-level summary of the period's
momentum. Keep it energetic but grounded.
[1–2 body paragraphs]
Narrative summary of what happened. Weave together completed work, meeting outcomes,
and key decisions. Don't just list — tell the story of progress.
---
### Budget
Reporting Period: Thru [DATE]
Total Hours Used: [X]
[BUDGET TABLE PLACEHOLDER]
---
### Timeline
- Projected Completion Date: [from SOW or previous update]
---
### Recent Highlights
- [Bullet per meaningful completed item, decision, or milestone]
- Keep to 6–10 bullets max
- Client-facing language only
---
### Looking Ahead
- [Bullet per upcoming task, next step, or open item needing client input]
- Flag any items requiring client action clearly
---
Please let me know if there are any items we may have missed or if there is anything
you would like to discuss in additional detail.
Cheers,
Andrew
Show the full draft in the chat as a clean, readable message (not HTML). Below the draft, add a short "Sources Used" summary — e.g.:
Sources used: 12 completed tasks (Apr 22–May 7), 3 Fathom meeting summaries (Apr 23, Apr 28, May 1), 4 Teamwork messages, 18 Slack messages (#smalley). Budget table left blank for manual entry.
Then ask:
"Want me to adjust the tone, add/remove anything, or post this to Teamwork once you're happy?"
Based on Andrew's existing updates, the tone should be:
Avoid: