Use the hold-first pattern for agent calendar events
Wire any agent that touches a calendar so it creates host-only HOLD events instead of real invites with attendees. The human promotes the HOLD to a real invite when ready. Calendar attendees never get an agent-generated invite they did not expect. Foundational pattern for any future calendar-related Auxot workflow.
Plus: two Admin-Agent passes: wire Google Calendar (or Outlook Calendar) with a tool policy that allows host-only event creation, and block any tool that adds attendees or updates shared meetings.
| Audience | Admins · Developers · Everyone |
|---|---|
| Time | ~10 min |
| Prerequisites | An Auxot account on any tier. A Google Workspace or Microsoft 365 account. Comfort wiring an MCP server ([Add an MCP server](/tutorials/add-an-mcp-server)) and writing a tool policy ([Define a tool policy](/tutorials/define-a-tool-policy)). |
| You'll end up with | A connected calendar MCP scoped to host-only event creation, an agent tool policy that blocks attendee-adding tools and shared-meeting updates, and a one-paragraph operating note explaining the HOLD-to-real-invite promotion step. |
When a tutorial shows italic text in quotation marks, it usually mirrors a label or helper string inside Auxot. Product copy changes between releases — if something reads differently in your workspace, trust what you see on screen.
Callouts with a Worth knowing gold accent are meant as must-read context before you move on. Blockquotes that open with Tip are lighter, optional depth.
Why this matters
Calendar invites have a recipient. Once an agent sends an invite to a real attendee, the attendee gets a notification, the attendee’s calendar shows the event, and the attendee assumes the meeting is happening. If the agent got the meeting wrong (wrong attendee, wrong time, wrong context), the recovery is a cancellation email and a small reputation hit. If the agent does this often, the team’s invites stop being trusted.
The hold-first pattern fixes this structurally. The agent creates a host-only event on the team member’s calendar: title HOLD: <topic>, time, duration, no attendees besides the host, no invites sent. The human reviews the HOLD on their calendar, decides whether the meeting should happen, and if so promotes the HOLD to a real invite (adds attendees, updates the title, sends the invite). The promotion is the human decision; the agent does not make it.
This is different from “agent drafts an invite and waits for human approval.” A drafted invite still exists somewhere as an unsent artifact requiring its own UI to review. A HOLD event is already on the calendar in the natural place the human looks for upcoming meetings. The review happens during normal calendar inspection; the agent’s work is visible without an Auxot side-channel.
Nothing reaches an attendee’s inbox: you review the HOLD on your calendar, you promote to a real invite (or delete) when ready.
Quick start
- Wire the calendar MCP (Add an MCP server). For Google Workspace, use Google Calendar’s hosted MCP. For Microsoft 365, use Composio Outlook (calendar tools are part of the Composio Outlook surface in May 2026; Microsoft’s first-party Calendar MCP is in preview but not generally available).
- Review the calendar tool surface. The MCP typically exposes
create_event,update_event,add_attendees,send_invite,delete_event, and read tools. The agent needscreate_eventonly; everything else is gated. - Write the tool policy (Define a tool policy). Allow
create_eventonly when the attendee-list parameter is empty (host-only). Blockadd_attendees. Blockupdate_eventon any event with attendees besides the host. Blocksend_invite. The agent has one calendar-write path: creating host-only HOLDs. - Test the policy. Ask the agent to create a calendar event for tomorrow with another attendee. The policy should reject the call. Then ask the agent to create a host-only HOLD; the call should succeed and the event should appear on the host’s calendar with the HOLD prefix.
- Write a one-paragraph operating note explaining the HOLD-promotion step. The note’s job: tell the team how to promote HOLDs and when to delete them.
Done? A connected calendar MCP, a tool policy that prevents the agent from inviting attendees, and a written note your team reads when they see their first HOLD event.
The agent can do that?
1. Inventory the calendar tool surface and pick the agent’s scope
Chat → Admin Agent:
Calendar MCP: [Google Calendar hosted / Composio Outlook]. The agent will create host-only HOLD events for proposed meetings; the human promotes HOLDs to real invites when ready. Job: list the calendar tools the MCP exposes, group them as: (1) host-only event creation (allow), (2) attendee-adding tools (block), (3) event-update tools that could touch shared meetings (block, with the exception of host-only HOLD edits), (4) read tools (allow). Output a paste-ready tool-policy spec.
Why it’s non-obvious: Calendar MCPs differ in tool granularity. Google Calendar’s hosted MCP separates create_event and add_attendees cleanly; Composio Outlook bundles them sometimes. The agent’s inventory exposes the per-MCP shape; the policy follows the inventory.
2. Lock the tool policy
Tool policy target: [Google Calendar hosted MCP / Composio Outlook]. Allowed: `create_event` only when attendees field is empty (host-only HOLD). Blocked: `add_attendees`, `send_invite`, `update_event` on any event with attendees besides the host. The agent can update its own HOLD events (title, time, duration) but cannot touch events with non-host attendees. List the tool-policy rules and flag any tool that exposes both a "create" and a "modify-existing" surface where the policy needs to distinguish them.
Why it’s non-obvious: The agent should be able to edit its own HOLD events (it might want to adjust the time after receiving more context). But it should not be able to edit an existing shared meeting (a meeting with attendees). The policy needs to gate update_event on the attendee-list state of the target event, which is a parameter-level rule, not a tool-name rule.
3. Operating note for the team
Calendar MCP: [name]. Agents creating HOLDs: [list]. Produce a one-paragraph operating note: (1) the agent creates host-only HOLDs prefixed with "HOLD:" on the host's calendar; (2) the host reviews HOLDs during normal calendar inspection; (3) to promote, the host opens the HOLD, removes the prefix, adds attendees, sends the invite; (4) to dismiss, the host deletes the event; (5) HOLDs should be reviewed within [cadence, e.g., 24 hours] before they go stale; (6) what to do if a HOLD ends up with attendees the agent did not intend (the policy was loosened or a parameter slipped through; audit and re-secure). Tone: factual.
Why it’s non-obvious: The hold-first pattern is unfamiliar to most teams the first time they see it. A HOLD event with no attendees and a strange prefix looks like a mistake until someone explains it. The operating note is the explanation; it lives where the team will look when they encounter their first HOLD.
Go deeper
Why host-only, not “tentative”
Calendar systems support tentative status on events with attendees; the attendee receives an invite marked tentative. This is not the hold-first pattern; the attendee still gets a notification. The hold-first pattern is structurally different: no attendees, no notification, the event exists only on the host’s calendar until promoted.
Why the agent should not touch shared meetings
Existing meetings with multiple attendees represent commitments other people have made. An agent updating those meetings (changing time, changing attendees, changing title) sends notifications to every attendee and disrupts whatever calendars are already configured around the original time. The agent does not have the context (was the original time chosen for a reason? does the new time conflict with attendee X’s other commitment?) to make this change safely. The policy blocks update_event on shared meetings to prevent the agent from making this decision.
Per-MCP wiring notes
For Google Calendar, the hosted MCP became generally available in 2025 for Google Workspace accounts. OAuth scopes: calendar.events for write access, calendar.readonly for read. Confirm the scopes during the wiring step. Google Calendar’s tool surface is the cleanest: create_event accepts an attendees parameter that the policy can require to be empty.
For Microsoft 365, the path is Composio Outlook (the calendar tools are part of the Outlook MCP surface). Microsoft’s first-party Calendar MCP is in preview as of May 2026; when it becomes generally available, migrate the wiring. The tool-policy discipline stays the same.
For Apple Calendar / iCloud, no MCP path is available in May 2026. Teams on Apple-only calendars cannot use the hold-first pattern via Auxot until an iCloud MCP exists; the workaround is to have the agent draft the meeting in a shared doc and a human create the calendar event manually.
Hold-first vs draft-invite workflows
Some teams prefer the agent to draft an invite (with attendees pre-filled in the draft) and leave it for human review in a holding area. This is a valid alternative to hold-first; the trade-off is that the holding area is a separate UI to monitor (a shared doc, a Slack channel, an Auxot human-step) and the calendar review habit does not catch unreviewed drafts. The hold-first pattern uses the calendar as the review surface, which most teams already check. Pick the pattern that matches your team’s review habits.
Troubleshooting
- The agent created an event with attendees. The policy was loosened or the
create_eventattendees parameter was not constrained to empty. Audit the policy and re-secure. - HOLDs are piling up without review. The host is not reviewing their calendar regularly. The hold-first pattern depends on the review habit; if the habit is missing, switch to a draft-invite workflow with a shared-doc review surface.
- The HOLD prefix is not appearing. The agent’s
create_eventcall did not include the prefix in the title. Reinforce the prefix in the agent’s instructions; the prefix is what makes the HOLD recognizable. - The agent tried to update an existing shared meeting. The policy correctly blocked it. The agent’s instructions might be over-broad (asking the agent to “manage” the calendar implies updates). Scope the instructions to “propose HOLDs,” not “manage the calendar.”
Variations and edge cases
- The agent needs to propose multiple slots for one meeting. Create multiple HOLDs, one per slot, all on the host’s calendar. The host picks one to promote, deletes the others. Mention this pattern in the operating note so the host expects multiple HOLDs from one agent run.
- The agent should suggest meeting times based on the host’s availability. The agent reads the calendar (allowed via read tools), proposes times via HOLD events. Do not let the agent read other people’s calendars without explicit permission; that scope is broader than the hold-first pattern needs.
- The team uses a shared calendar (an account everyone has write access to). HOLDs on a shared calendar are visible to everyone; this might be appropriate for a team-availability calendar or inappropriate for individual scheduling. Decide which case applies before wiring the MCP.
- The agent needs to create recurring HOLDs. Most calendar MCPs support recurrence in the
create_eventcall. The recurrence is part of the HOLD; the human promotes the entire series at once (or splits it during promotion). Verify the MCP exposes recurrence parameters before wiring an agent that depends on them.
Walkthrough
Step 1: Open the MCP-server settings
Open Settings → MCP servers in Auxot. Click Add server. Search for “Calendar” (or “Google Calendar” / “Outlook Calendar”) in the catalog.
Step 2: Pick the calendar MCP
For Google Workspace, pick Google Calendar’s hosted MCP. For Microsoft 365, pick Composio Outlook (calendar tools are part of the Outlook MCP). For Apple Calendar, no MCP path is available; switch to a draft-invite workflow.
Step 3: Walk through the OAuth flow
Click connect. The OAuth flow opens in a new tab. Sign in with the host’s account. Review the scopes; the calendar MCP requests calendar read and write. Confirm there is no scope for cross-user calendar access unless the host has been delegated.
Step 4: Verify the connection
Run a read tool call (the agent should list upcoming events on the host’s calendar). Verify the agent can see events; the read scope is needed for the agent to know what times the host is available when proposing HOLDs.
Step 5: Write the tool policy
Open Settings → Tool Policies (Define a tool policy). Allow create_event when the attendees field is empty. Block add_attendees. Block update_event on any event with attendees besides the host. Block send_invite. Save.
Step 6: Test the HOLD-creation path
Ask the agent to propose a HOLD for tomorrow at 2pm. The agent should create the event with no attendees and a “HOLD:” title prefix. Open the host’s calendar; verify the event is there. Then ask the agent to send an invite to a real attendee; the policy should reject the call.
What’s next
- → Prep for your next sales call. A natural place to apply this pattern: the agent proposes a sales-call HOLD; the rep promotes to a real invite once the prospect responds.
- → Triage and follow up on inbound leads. Lead-followup workflows often want a calendar HOLD as the next-step artifact.
- → Add an MCP server. The MCP wiring foundation this tutorial builds on.
- → Define a tool policy. The attendee-list-empty constraint that makes the hold-first pattern structural.
- → Use a DRAFT_ tab for agent spreadsheet writes. The same review-surface-as-natural-habit principle applied to spreadsheets.
- → Keep send_email out of your agent tool policies. The same review-gate principle applied to email.
Reference
- The pattern: agent creates host-only events prefixed with “HOLD:” on the host’s calendar; the human promotes to a real invite (or deletes) during normal calendar review.
- Tool policy shape: allow
create_eventwhen attendees field is empty; blockadd_attendees; blockupdate_eventon shared meetings; blocksend_invite. - The structural review gate: the host’s calendar. The team’s existing calendar-review habit IS the review step.
- HOLD title convention: prefix with “HOLD:” (or your team’s convention). The prefix makes the event recognizable as an agent proposal.
- Per-MCP path: Google Calendar hosted MCP (Google Workspace, generally available), Composio Outlook (Microsoft 365, calendar tools are part of the Outlook MCP), no path for Apple Calendar / iCloud as of May 2026.
- When the pattern is not a fit: teams that do not review their calendars regularly. HOLDs stack up unreviewed. Switch to a draft-invite workflow with a shared-doc review surface.
- Variations: multi-slot HOLDs (one per proposed time), recurring HOLDs, shared-calendar HOLDs (visible to the team).
- What this pattern is not: a way for the agent to schedule meetings autonomously. The promotion to a real invite is always a human decision.
- Operating note discipline: lives beside the policy doc; explains the HOLD-prefix and promotion step so a team member encountering their first HOLD knows what it is.