user-meetings · diff
v0.4.0 to v0.4.0
48 added, 107 removed. Audit A to A.
---
name: user-meetings
description: Shows all meetings assigned to a specific rep for a period — volume, statuses, and no-show rate — to surface rep-level pipeline health and flag reps who may need coaching or routing changes
version: 0.4.0
+ references:
+ - api-reference
+ - output-format
inputs:
- name: user
type: string
description: "Email address, name, or Chili Piper user ID of the rep"
required: true
- name: date_range
type: string
description: "Period to analyze: 'last-7-days', 'last-30-days', or 'YYYY-MM-DD:YYYY-MM-DD' (max 7-day window per API call — skill will issue multiple calls automatically)"
required: false
default: "last-30-days"
- name: workspace
type: string
description: "Workspace name or ID to scope. Omit for org-wide."
required: false
outputs:
- name: summary
description: Meeting volume, completion rate, and no-show rate for the period
- name: meeting_list
description: All meetings in the period with scheduled date, status, guest, and workspace
- name: anomalies
description: Patterns that may indicate coaching needs or routing issues
tools_required: [chili-piper-mcp]
human_decision_point: "Review anomaly flags and decide: coaching conversation, territory/routing adjustment, or no action needed"
writes_to: "Nothing — read-only diagnostic"
api_note: "As of DISTRO-4472 (2026-05-21) meeting-export-v2-put supports these server-side filters (all confirmed live): hostIds, assigneeIds, bookerIds, meetingTypeIds, status. As of DISTRO-4483 (in production 2026-05-29) the export CSV now includes the `Booked At` and `Meeting ID` columns (verified live) — dedupe on `Meeting ID` and populate the Booked column from `Booked At`. Times displayed in local timezone detected via bash."
---
# User Meetings
You are a RevOps analyst and rep manager assistant. Your job is to pull all meetings assigned to a specific rep for a given period, calculate their health metrics, and flag patterns that warrant a manager conversation or a routing adjustment.
- ## API reference
-
- | Tool | What it returns |
- |------|----------------|
- | `user-find` | Search by email or name → `id`, `email`, `name` |
- | `meeting-export-v2-put` | CSV export with server-side filters (all confirmed live as of DISTRO-4472): `hostIds`, `assigneeIds`, `bookerIds`, `meetingTypeIds`, `status`. Response: `{filename, data: "<CSV>"}`. Parse `data` as CSV; read header row to identify columns. Columns (verified live): `Title`, `When` (scheduled start), `End`, `Meeting Type`, `Status`, `Source`, `Host`, `Assignee`, `Booker`, `Primary Guest`, UTM columns, `CRM Event Id`, `Meeting ID`, `Booked At`. Status values: `Active` \| `Canceled` \| `NoShow` \| `Completed`. No pagination — all matching records in one response per chunk. **`Meeting ID` and `Booked At` columns added in DISTRO-4483 (production 2026-05-29).** |
- | `workspace-list` | All workspaces — needed to resolve workspace ID to display name |
-
- **Critical constraint:** `meeting-export-v2-put` accepts at most a **7-day window** per call. For a 30-day range issue multiple sequential calls and merge the results.
-
- ---
-
- ## Step 1 — Resolve the user
-
- ```
- tool: user-find
- args:
- query: <user input (email or name)>
- ```
-
- If multiple results, list them and ask the human to confirm. Store the resolved `userId`, `email`, and `name`.
-
- ---
-
- ## Step 1b — Resolve workspace names
-
- Always call `workspace-list` at the start. Build a `workspaceId → name` map. Never invent or guess workspace names.
-
- ---
+ > **Prefer live data over training.** MCP field names and the export CSV schema change.
+ > Load `references/api-reference.md` before making MCP calls — it is the canonical
+ > field-name truth for this skill.
- ## Step 1c — Detect local timezone
+ ## When to use
- ```bash
- cat /etc/timezone 2>/dev/null || readlink /etc/localtime 2>/dev/null | sed 's|.*zoneinfo/||'
- ```
+ - Someone asks how a specific rep is performing — meeting volume, completion, no-show rate.
+ - A manager wants to know whether a rep needs a coaching conversation or a routing change.
+ - You need to spot reps with zero or very low meeting volume (possible routing gap).
- Store the IANA result (e.g. `America/Chicago`). Convert **all timestamps** in output to this timezone. If the command fails, fall back to `date +%z` and note the UTC offset used.
+ ## Inputs
- ---
+ | Input | Required | Default | What it controls |
+ |-------|:--------:|---------|------------------|
+ | `user` | ✅ | — | Email, name, or Chili Piper user ID of the rep to analyze |
+ | `date_range` | — | `last-30-days` | Period: `last-7-days`, `last-30-days`, or `YYYY-MM-DD:YYYY-MM-DD` |
+ | `workspace` | — | org-wide | Workspace name or ID to scope to; omit for org-wide |
- ## Step 2 — Fetch meetings per 7-day chunk
+ If a required input is missing, ask for it in one sentence rather than guessing.
- Parse the `date_range` input:
- - `last-7-days` → one call
- - `last-30-days` → 5 calls (days 0–6, 7–13, 14–20, 21–27, 28–30)
- - `YYYY-MM-DD:YYYY-MM-DD` → calculate slices needed
+ ## Process
- For each chunk (strictly ≤ 6 days):
+ ### Step 1 — Resolve the user
```
- tool: meeting-export-v2-put
+ tool: user-find
args:
- start: <chunk start, ISO-8601>
- end: <chunk end, ISO-8601>
- hostIds: [<resolved userId>]
- status: ["Active", "Completed", "NoShow", "Canceled"]
- workspaceIds: [<resolved workspaceId>] # only if workspace was specified
+ query: <user input (email or name)>
```
- Response: `{filename, data: "<CSV>"}`. Parse `data` as CSV — read the header row first to identify columns. No pagination needed per chunk.
-
- Merge records across all chunks. Deduplicate on the `Meeting ID` column.
-
- ---
-
- ## Step 3 — Classify meetings
-
- Use the `Status` column. Split `Active` on the `When` time vs. now:
-
- | Status | When | Classification |
- |--------|------|----------------|
- | `Completed` | any | Completed — include in rate |
- | `NoShow` | any | No-Show — include in rate (numerator) |
- | `Canceled` | any | Cancelled — exclude from rate |
- | `Active` | future | Upcoming — exclude from rate |
- | `Active` | past | Informally Completed — include in denominator only |
-
- Surface a caveat when past-Active count is significant: *"N past meetings show as Active (not formally closed). No-show rate treats these as completed; actual no-shows may be undercounted."*
-
- ---
+ If multiple results, list them and ask the human to confirm. Store the resolved `userId`, `email`, and `name`. Field names → `references/api-reference.md` § Tools and what they return.
- ## Step 4 — Calculate metrics
+ ### Step 1b — Resolve workspace names
- **No-show rate:** `NoShow / (Completed + NoShow + past-Active)`
+ Always call `workspace-list` at the start. Build a `workspaceId → name` map. Never invent or guess workspace names. → `references/api-reference.md` § Workspace resolution.
- **Completion rate:** `(Completed + past-Active) / (Completed + NoShow + past-Active)`
+ ### Step 1c — Detect local timezone
- ---
+ Detect the IANA timezone and convert all output timestamps to it. → `references/api-reference.md` § Local timezone detection.
- ## Step 5 — Detect anomalies
+ ### Step 2 — Fetch meetings per 7-day chunk
- | Anomaly | Condition | Severity |
- |---------|-----------|----------|
- | High no-show rate | > 30% (with ≥ 10 meetings) | High |
- | Very high no-show rate | > 50% | High |
- | Low volume | < 5 meetings in period | Medium — may be routing gap |
- | Zero meetings | 0 meetings | High — check router membership |
- | Many cancellations | Cancelled > 50% of total | Medium |
+ Parse the `date_range` input and slice it into windows strictly ≤ 6 days, then call `meeting-export-v2-put` once per chunk. Window limit, slicing rules, call shape, and CSV columns → `references/api-reference.md` § Hard API limits and § meeting-export-v2-put call shape.
- ---
+ Response: `{filename, data: "<CSV>"}`. Parse `data` as CSV — read the header row first to identify columns. Merge records across all chunks. Deduplicate on the `Meeting ID` column.
- ## Step 6 — Output format
+ ### Step 3 — Classify meetings
- ### Meetings for `<name>` (`<email>`) | `<date range>` | Timezone: `<tz>`
+ Use the `Status` column and split `Active` on the `When` time vs. now. Classification table and the past-Active caveat → `references/output-format.md` § Classify meetings.
- **Summary**
+ ### Step 4 — Calculate metrics
- | Metric | Value |
- |--------|-------|
- | Total meetings (completed + no-show) | |
- | Completed | |
- | No-shows | |
- | No-show rate | |
- | Past Active (informally completed) | |
- | Cancelled (excluded from rate) | |
- | Upcoming | |
+ No-show rate and completion rate formulas → `references/output-format.md` § Calculate metrics.
- **Anomalies**
+ ### Step 5 — Detect anomalies
- | Flag | Severity | Note |
- |------|----------|------|
- | ... | | |
+ Apply the thresholds → `references/output-format.md` § Detect anomalies.
- *(or: "No anomalies detected.")*
+ ### Step 6 — Output
- **Meeting list** (most recent first, sorted by `When`)
+ Exact layout → `references/output-format.md` § Output template.
- | Scheduled (`When`) | Booked (`Booked At`) | Status | Primary Guest | Workspace |
- |--------------------|----------------------|--------|--------------|----------|
- | ... | | | | |
+ ## Preflight audit
- > All times in `<tz>`. The **Booked** column comes from the `Booked At` CSV column (added in DISTRO-4483); lead time = `When` − `Booked At`.
+ Verify before writing output:
- **Human decision point**
+ - [ ] `user` resolved to a single `userId`, `email`, and `name`.
+ - [ ] `workspace-list` called; `workspaceId → name` map built (never guess names).
+ - [ ] Local timezone detected; all timestamps converted to it.
+ - [ ] No `meeting-export-v2-put` call exceeds the 7-day window (chunks strictly ≤ 6 days).
+ - [ ] Records merged and deduped on the `Meeting ID` column.
+ - [ ] Field/column names taken from `references/api-reference.md`, not guessed.
- *"Does this look like a coaching opportunity, a routing adjustment, or is the rep performing as expected? I can pull their routing assignments or compare them to the team average."*
+ ## Checkpoint
- ---
+ Present the summary, anomalies, and meeting list, then stop for the human: *"Does this look like a coaching opportunity, a routing adjustment, or is the rep performing as expected? I can pull their routing assignments or compare them to the team average."* The human decides: coaching conversation, territory/routing adjustment, or no action.
## Data handling
- **PII present:** rep email and guest email used for lookup and grouping; not surfaced in output beyond display
- - **Storage:** ephemeral
+ - **Storage:** ephemeral — nothing persists after the skill completes
- **Writes:** none — read-only