Agent: read this first
You're working in the Vendor contract renewal tracker workspace at trydock.ai/<org>/vendor-contract-renewal-tracker.
## Your role
Reads Contracts daily, flags every renewal hitting a 90 / 60 / 30 day window, drafts a 3-5 sentence renewal recommendation per contract, appends to Renewal alerts and Status. Never modifies Contracts.status or Contracts.allocated without owner sign-off.
## Cadence, when to update Dock
- After EVERY tool call that changes state (row create / update, doc append), append an entry to the **Status** surface.
- After every milestone, update the canonical doc surface for that work.
- When you start a session, READ the last 5 Status entries first to know what happened since you last worked.
## User-loop protocol
- End EVERY reply to the user with: "Check Dock for the latest at trydock.ai/<org>/vendor-contract-renewal-tracker."
- If you make a decision the user might want to override (priority, scope cut, tone change), append to **Status** AND mention it in your reply: "Decided X. If you'd rather Y, edit [surface] and I'll re-plan."
- If you're blocked, post to Status with prefix `BLOCKED:` and ask one specific question.
## Don't touch
- Canonical phase / column / surface titles.
- Anything in a section titled "Locked" or "Decisions sealed."
- The agentPrompt itself (this section).
## First tool calls
1. `list_surfaces(workspace_slug="vendor-contract-renewal-tracker")`
2. `get_doc(workspace_slug="vendor-contract-renewal-tracker", surface_slug="status")`
3. `list_rows(workspace_slug="vendor-contract-renewal-tracker", surface_slug="contracts")`
---
# Vendor contract renewal tracker
A rolling daily check on every vendor contract. Open in Dock and you get four surfaces seeded:
- **Contracts** (table) one row per vendor contract: vendor, category, annual value, renewal date, owner, auto-renew, notice period, notes, status.
- **Setup guide** (doc) how the agent connects to your data + the Python recipe for cron / CueAPI scheduling.
- **Renewal alerts** (doc) running log of every alert the agent posts. Newest at top. Includes the recommendation, posted-at timestamp, and the contract row link.
- **Status** (doc) the agent's working session log. End of every run: 1 paragraph of what happened, what's pending.
## Bring your own agent
Connect one agent to this workspace (Claude in Cursor, Claude Code, Codex, any MCP client). The agent reads Contracts every morning, no manual trigger needed once the daily cron is wired.
## The user-loop protocol
Your agent proposes; you decide.
- Daily 9 AM: agent reads every Contracts row, computes days-to-renewal, flags any contract hitting 90 / 60 / 30 day windows for the first time (the row has an "Alert sent (90d)" column the agent ticks).
- For each flagged contract: agent drafts a 3-5 sentence recommendation (renew / renegotiate / competitive bid), posts a Renewal alerts entry, and Slack-pings the owner if SLACK_WEBHOOK_URL is set.
- Agent NEVER changes Contracts.status, Contracts.annual_value, or Contracts.auto_renew. Those are operator decisions.
- End of every working session, agent writes 1 paragraph to **Status**: contracts scanned today, alerts sent, next due dates.
## First run
1. Populate Contracts with every vendor relationship you have. Minimum required fields: Vendor, Renewal Date (YYYY-MM-DD), Annual Value, Owner.
2. Open Setup guide and follow the install steps. Either run the script on cron locally, or schedule via CueAPI.
3. Watch Status. After the first run you should see a session note.
## Status
### [00:00 UTC] seeded by Dock
Workspace created from the vendor contract renewal tracker template. Agent: read the Setup guide, then run a first scan of Contracts. Post first Status entry after.
Next: read setup guide + first scan.
Outcome
A rolling daily workspace where every vendor contract has one row, the agent surfaces upcoming renewals at 90 / 60 / 30 days out with a tailored recommendation, and you never get caught flat-footed by an auto-renew that fired without notice.
Estimated time: 1 hour first-time setup, ongoing ~5 min/day review
Difficulty: beginner
For: Ops + finance leads at PE-backed mid-market companies managing a vendor portfolio.
What you'll need
Pre-register or install before you start.
- Dock (Free plan covers this template; Pro $19/mo unlocks more workspaces.) — The workspace itself, the source of truth for contracts + the place every alert is logged.
- Anthropic API (Pay per token, ~$0.005 per recommendation on Sonnet.) — Claude drafts the 3-5 sentence renewal recommendation per contract.
- Slack incoming webhook (Free) — Optional alert destination so the contract owner sees the recommendation without opening Dock.
- CueAPI (optional) (Free tier covers daily cadence.) — Cloud-scheduled run so the daily scan keeps working when your laptop is closed.
The template · 5 steps
Step 1: Seed Contracts with every vendor relationship
Estimated time: 30-60 min for a first sweep
Populate the Contracts table with one row per vendor contract you currently have running. The minimum required fields are Vendor, Renewal Date (YYYY-MM-DD), Annual Value, and Owner. The richer the Notes, the better the agent's recommendation. Auto-Renew, Notice Period (Days), Category, and Status columns are pre-created and fillable as you learn each contract's terms.
Tasks
- List every vendor relationship (software, facilities, professional services, logistics)
- For each: pull the latest signed contract, find the renewal date + notice period
- Create Contracts rows: Vendor, Category, Annual Value, Renewal Date (YYYY-MM-DD), Owner, Auto-Renew (Yes/No/Unknown), Notice Period (Days), Notes, Status (Active by default)
- If you don't have the contract in hand, mark Status as Under Review and add to Notes what you need
[!CAUTION] Gotchas
- Renewal Date must be ISO YYYY-MM-DD. Anything else and the agent skips the row.
- Annual Value is the operator's number. If the contract has tiered pricing, use the current tier; don't average.
- Auto-Renew = Unknown is fine. The agent surfaces the contract earlier (90 days) when Auto-Renew is Yes or Unknown.
Step 2: Install the daily renewal-check script
Estimated time: 15 min
The agent's daily routine is a Python script that reads Contracts via the Dock REST API, computes days-to-renewal per row, drafts the recommendation via the Anthropic API, posts to Slack (optional), and ticks the row's alert columns. Install it locally or in your cron host.
Tasks
- Open Setup guide (doc) and copy check_renewals.py into a local folder
- Run pip install anthropic requests python-dotenv
- Create a .env with DOCK_API_KEY, DOCK_WORKSPACE_SLUG, ANTHROPIC_API_KEY, SLACK_WEBHOOK_URL (optional), ALERT_WINDOWS=90,60,30, CURRENCY_SYMBOL=$, CLAUDE_MODEL=claude-sonnet-4-6
- Generate a Dock API key at trydock.ai/settings/api
- Run python check_renewals.py once manually. Watch Renewal alerts + Status for the first entries
[!CAUTION] Gotchas
- DOCK_WORKSPACE_SLUG must match the workspace you forked this template into. If you renamed the workspace, update the env var.
- If a 90-day alert fires for a contract that was just renewed but the row wasn't updated, the agent will alert again at 60 days. Update Status=Renewed when the renewal is confirmed and the agent will skip past windows.
Step 3: Schedule the daily run
Estimated time: 10 min
Pick one of two paths to run the script every morning. Cron is simplest if you have an always-on Mac or Linux box. CueAPI is the right pick if you want cloud-scheduled execution that survives your laptop closing.
Tasks
- Option A — cron: crontab -e, add
0 9 * * * cd /path/to/script && source .env && python3 check_renewals.py >> renewal_check.log 2>&1 - Option B — CueAPI: pip install cueapi cueapi-worker, then cueapi create --name vendor-contract-renewal-check --schedule '0 9 * * *' --handler ./check_renewals.py
- Either way: confirm the next morning that Status has a fresh session entry
[!CAUTION] Gotchas
- Cron requires the machine awake at 9 AM. If you close your laptop overnight, switch to CueAPI.
- CueAPI worker must be running for cues to fire. Run cueapi-worker start once + supervise it with launchd / systemd.
Agent prompt for this step
Run a first scan of the Contracts table. For every row with a Renewal Date set, compute days until renewal. For any row inside a 90 / 60 / 30 day window that hasn't been alerted yet (the "Alert Sent (Xd)" column is blank), draft a recommendation (renew / renegotiate / bid) and append to Renewal alerts. Tick the alert column. Post a Status entry summarizing: rows scanned, alerts sent, next renewal due.
Step 4: Wire the optional Slack alert
Estimated time: 5 min
If your contract owners live in Slack, post each recommendation there. Create one incoming webhook for the ops or finance channel, paste it into SLACK_WEBHOOK_URL. The script already builds a clean Block Kit message: header with urgency emoji (90 yellow, 60 orange, 30 red), section with contract details, recommendation, and a back-link to the Dock workspace.
Tasks
- Create an incoming webhook at api.slack.com/apps → New App → From scratch → Incoming Webhooks → Add to channel
- Paste the webhook URL into SLACK_WEBHOOK_URL in .env
- Manually trigger a scan to verify the message lands in the right channel
Step 5: Set the renewal-decision review cadence
Estimated time: 15 min/week ongoing
The agent surfaces; the owner decides. Pick a weekly time to review Renewal alerts (Friday 4 PM is the operator default), make the renew / renegotiate / bid call, update Contracts.status accordingly, and message the vendor before the notice period lapses.
Tasks
- Block 15 min on the calendar weekly (Friday 4 PM default)
- Open Renewal alerts (doc). Walk through every alert since last review
- For each: confirm or override the agent's recommendation, update Contracts.status (Active / Renewed / Under Review / Cancelled)
- Message the vendor with renewal / renegotiation / bid intent
[!CAUTION] Gotchas
- If you don't act on a 30-day alert and the contract has auto-renew, you will renew at the existing terms. Default Contracts.status=Renewed only after you've explicitly confirmed terms.
Hand the template to your agent
Paste the prompt below into your agent's permanent system prompt so the agent reads, writes, and maintains this workspace as you work through the steps.
You are the agent running on the "Vendor contract renewal tracker" template workspace, connected via MCP at your-org/vendor-contract-renewal-tracker.
Your job: surface every vendor contract that's hitting a 90 / 60 / 30 day renewal window, draft a renew-or-renegotiate recommendation per contract, log to Renewal alerts + Status. Never modify contract terms.
User-loop protocol:
- You propose. The owner decides. Never change Contracts.status, Contracts.annual_value, Contracts.auto_renew, or Contracts.owner.
- Daily 9 AM (or "scan renewals"): read all Contracts rows. For each row with a Renewal Date in YYYY-MM-DD, compute days until renewal. For each unticked 90 / 60 / 30 day window the contract is now inside, draft a recommendation and post an alert.
- Recommendation must cover: (1) renew vs renegotiate vs competitive bid; (2) the risk if no action is taken before the notice period lapses; (3) one specific next step for the owner. 3-5 sentences. No filler, no hedging.
- Post the recommendation as a new entry at the top of Renewal alerts doc, prefixed with a timestamp and the contract vendor. Tick the "Alert Sent (90d)" / "(60d)" / "(30d)" column on the Contracts row so the same window doesn't fire twice.
- If SLACK_WEBHOOK_URL is set, post a Slack alert with the vendor, renewal date, annual value, and recommendation.
- End of every working session, write 1 paragraph to Status: how many contracts scanned, how many alerts sent, the next renewal due.
Don't touch:
- Contracts.status (Active / Cancelled / Renewed / Under Review is the operator's tag).
- Contracts.annual_value / .notice_period_days (those are the operator's source of truth from the original contract).
- Renewal alerts entries older than 30 days (those are history).
First MCP tool calls:
1. list_surfaces(workspace_slug="vendor-contract-renewal-tracker")
2. list_rows(workspace_slug="vendor-contract-renewal-tracker", surface_slug="contracts")
3. get_doc(workspace_slug="vendor-contract-renewal-tracker", surface_slug="status")
FAQ
How does this know which contracts are coming up?
A daily Python script reads the Contracts table from this Dock workspace, computes days until each row's Renewal Date, and fires an alert the first time a contract enters the 90 / 60 / 30 day window. Each alert is tracked on the row itself so the same window doesn't fire twice.
Does the agent renew or cancel contracts on my behalf?
No. The agent surfaces upcoming renewals and drafts a recommendation for each. You decide and message the vendor. The agent doesn't touch Contracts.status, Annual Value, or Auto-Renew — those are operator-only fields.
What if I don't have Slack?
Skip the SLACK_WEBHOOK_URL env var. The agent still appends every alert to the Renewal alerts doc surface and the Status doc surface inside Dock. You'll see them when you open the workspace.
Can I change the alert windows?
Yes. Set ALERT_WINDOWS in .env to a comma-separated list of day counts. The default is 90,60,30. If you only want one alert, set it to 60. If you want earlier visibility for high-value contracts, set 120,90,60,30. The script and the agent both read this value.
Does this work with Salesforce / HubSpot for contract data?
Not in v1 — Contracts is the canonical source. The script reads from the Dock table. A future extension can pull contract metadata from a connected CRM or CLM (Ironclad, ContractWorks, Spotdraft) on a daily sync and write to Contracts.