A Monday-morning workspace where every open deal has one row scored Green / Yellow / Red, a markdown coverage report drafted for the sales meeting, and an agent that never edits CRM fields on its own.
A Monday-morning workspace where every open deal has one row scored Green / Yellow / Red, a markdown coverage report drafted for the sales meeting, and an agent that never edits CRM fields on its own.
Time45 min setup, ongoing ~10 min/week reviewDifficultybeginnerForVP Sales / Head of Revenue at $5M-$50M revenue companies running a weekly pipeline review.
How this works
Open it, hand it to your agent, walk the steps.
Paste this to your agent (Claude / Cursor / Codex)
You are the agent running on the "Weekly pipeline health report" template workspace, connected via MCP at your-org/weekly-pipeline-health-report.
Your job: every Monday at 6 AM, read every open deal from the CRM, score health, upsert one Pipeline row per deal, draft a weekly Reports section, post a Status entry. Never edit CRM fields.
User-loop protocol:
- You propose. The rep decides. Never edit Amount, Stage, Close Date, or Owner in the CRM. Those are rep-only fields.
- Monday 6 AM (or "run pipeline report"): query CRM for all open deals (stage != Closed Won, Closed Lost) on the configured pipeline. For each deal: compute Days in Stage (today - stage entry date), Slip Count (number of close-date changes outward), Last Activity Days (today - last logged activity).
- Score Health per deal:
- Red: late stage with Last Activity Days >= 14, OR Slip Count >= 3, OR Close Date in the past with no Stage advance
- Yellow: Days in Stage > 2x stage-typical, OR Slip Count >= 1, OR Last Activity Days >= 7
- Green: everything else
- Upsert Pipeline row by CRM deal ID (existing row updates, new deal creates). Never delete Pipeline rows; closed deals get Health=Closed and stay for history.
- Draft this week's Reports section (markdown, new section at top): Coverage by Stage (count + amount sum per stage), Top 5 Red deals with one-line risk notes, Late-stage deals with no recent activity, Asks for owners (1-2 specific actions).
- If SLACK_WEBHOOK_URL is set: post a short Monday morning ping with top 3 risks + link back to Reports.
- End of every working session, write 1 paragraph to Status: deals scanned, Red count, Yellow count, Reports section drafted, next Monday's run.
Don't touch:
- CRM fields (Amount, Stage, Close Date, Owner).
- Pipeline rows older than the current run (only upserts on the live deal set; closed deals retain Health=Closed).
- Reports sections older than 8 weeks (those are history).
First MCP tool calls:
1. list_surfaces(workspace_slug="weekly-pipeline-health-report")
2. list_rows(workspace_slug="weekly-pipeline-health-report", surface_slug="pipeline")
3. get_doc(workspace_slug="weekly-pipeline-health-report", surface_slug="status")
Top to bottom. Each step has tasks, pointers, gotchas.
01 / 05
Confirm CRM access + pipeline ID
10 min
Pipeline-level scoring requires reading every open deal plus stage history plus activity timestamps. Confirm with the operator: which CRM, which pipeline, which stages are 'active' vs 'closed'. Multi-pipeline orgs must pick one pipeline per workspace; fork the template per pipeline if needed.
Tasks
Ask the operator which CRM (HubSpot, Salesforce, Pipedrive). Default script uses HubSpot.
Ask which pipeline ID. HubSpot orgs often have New Business, Renewal, Expansion as separate pipelines.
Generate a CRM token with read scopes for deals + companies + owners + engagements (HubSpot Private App).
Gotchas
Multi-pipeline orgs. One workspace = one pipeline. Don't try to mix New Business + Renewal in one report; the stages don't match.
Custom stages. If the org has custom stages, list them out and pick which count as active. Script has STAGE_TYPICAL_DAYS dict to tune.
02 / 05
Wire .env + the Python script
20 min
One script: run_pipeline_report.py runs every Monday at 6 AM. Reads CRM, computes health per deal, upserts Pipeline rows, drafts the Reports section, posts Status. Idempotent: re-running the same morning re-syncs against the current CRM state.
Tasks
Open Setup guide (doc) and copy run_pipeline_report.py into a local folder
Generate a Dock API key at trydock.ai/settings/api
Optional: create a Slack incoming webhook for the sales channel, paste into SLACK_WEBHOOK_URL
Gotchas
PIPELINE_ID. Find it via the CRM's pipelines endpoint. HubSpot: GET /crm/v3/pipelines/deals returns one entry per pipeline with a stable id.
Owner names. The script resolves owner IDs to display names via the Owners API + a local cache. Without crm.owners.read scope, rows show numeric IDs.
03 / 05
Run a first manual scan
20 min
Before scheduling, confirm the first run produces a sensible report. Run the script manually, open Pipeline + Reports + Status, and walk through with a senior rep to sanity-check the Red flags.
Tasks
python run_pipeline_report.py
Open Pipeline (table). Confirm one row per open deal with Health populated.
Open Reports (doc). Confirm the top section has Coverage by Stage, Top 5 Red deals, Asks.
Walk through Top 5 Red with a rep. If two of them look wrong, tune the Health rules in the script (raise the activity threshold, adjust STAGE_TYPICAL_DAYS).
Gotchas
First-run noise. New CRMs often have stale deals from years ago in active stages. Either close them in the CRM, or set INCLUDE_OLDER_THAN_DAYS=365 to skip them.
Activity logging gap. If reps don't log calls / emails, every deal will score Red. The fix is rep behavior, not script tuning; surface that in Status so the operator knows.
Agent prompt for this step
Run a first pipeline scan. Query CRM for every open deal on the configured PIPELINE_ID. For each deal: compute Days in Stage, Slip Count, Last Activity Days. Score Health = Green / Yellow / Red by the rules in the prompt. Upsert one Pipeline row per deal (by CRM deal ID). Draft a Reports section at the top of the Reports doc: Coverage by Stage, Top 5 Red deals, Late-stage deals with no recent activity, Asks. Post a Status entry summarizing: deals scanned, Red count, Yellow count, next Monday's run.
04 / 05
Schedule the Monday 6 AM run
10 min
One cron task: run weekly Monday at 6 AM. Before the team starts, after weekend close-date pushes settle. Idempotent: re-running the same Monday re-syncs to current CRM state.
Confirm the next Monday: Status has a fresh session entry + Reports has a new section at the top.
Gotchas
Closed laptop overnight + cron = no run. Switch to CueAPI for cloud-scheduled if your machine isn't always on.
Time zone. 6 AM is your laptop's tz under cron. CueAPI takes an explicit --timezone flag; pick the team's primary tz.
05 / 05
Make the report part of the Monday rep call
5 min one-time
The report only works if reps see it before the call. Pin the Reports doc URL into the team channel, link it from the calendar invite for the Monday pipeline meeting, and walk through Top 5 Red as the first 5 minutes of the call.
Tasks
Pin the Reports doc URL (trydock.ai/[org]/weekly-pipeline-health-report) to the sales Slack channel
Edit the Monday pipeline meeting invite. Paste the URL into the description so reps land on it from the calendar event
Use Top 5 Red as the first 5 minutes of the meeting. Each red deal: ask the owner one specific question from the Risk Notes.
After the meeting, owners update their Notes / Stage in the CRM. Next Monday's run picks up the changes.
Gotchas
If reps don't open Reports before the call, the report is wasted. Pin the URL in two places (channel + calendar event) so the link is unmissable.
FAQ
Common questions on this template.
Does the agent edit deals in my CRM?
No. The agent only reads from the CRM. Amount, Stage, Close Date, Owner are all rep-controlled fields that the agent never writes. The agent writes to Dock surfaces only: Pipeline rows, Reports sections, Status paragraphs.
How does it handle multi-pipeline orgs?
One workspace per pipeline. Fork this template per pipeline (New Business, Renewal, Expansion). The PIPELINE_ID env var locks each workspace to one pipeline so the stage rules align.
What if our reps don't log activities consistently?
Last Activity Days will trip every deal into Yellow or Red. The Health rules tune via env vars (ACTIVITY_YELLOW_DAYS, ACTIVITY_RED_DAYS), but the deeper fix is rep behavior. The Status entries will flag this so the operator sees the systemic issue.
Can I customize the Health scoring?
Yes. Open run_pipeline_report.py and adjust STAGE_TYPICAL_DAYS (dict of stage to expected days), ACTIVITY_YELLOW_DAYS / ACTIVITY_RED_DAYS, SLIP_RED_THRESHOLD. The Extending section in Setup guide shows how to add custom rules (e.g. Red on late-stage with no demo logged).
Does this work with Salesforce?
Yes with code edits. The default script targets HubSpot v3 CRM API. The Extending section in Setup guide shows the simple-salesforce swap: same compute logic, swap the fetch_open_deals() body to a SOQL query against Opportunity where IsClosed = false. Pipedrive is similar with python-pipedrive.
Open this template as a workspace.
We mint a fresh copy in your org with the steps as table rows, the pointers as a separate table, and the brief as a doc. Bring your agents, start checking off boxes.