Skip to main content
How-To Guides Last updated: 5 October 2026

How to Create Calendar Events

Schedule meetings and events through your AI assistant, including adding attendees and event descriptions.

Nathan Schram
By Nathan Schram Founder, Little Bear Apps

Schedule meetings, appointments, and events directly from your AI assistant with attendees and descriptions.

Create a Simple Event

“Add a meeting called Standup tomorrow at 9am for 30 minutes”

tool: create-event
params:
  subject: "Standup"
  start: "2026-03-02T09:00:00"
  end: "2026-03-02T09:30:00"

Times use ISO 8601 format. The server uses your configured timezone (default: Australia/Melbourne).

Add Attendees

“Schedule a team review with Alice and Bob for next Monday at 2pm”

tool: create-event
params:
  subject: "Team Review"
  start: "2026-03-09T14:00:00"
  end: "2026-03-09T15:00:00"
  attendees: ["alice@company.com", "bob@company.com"]

Attendees receive a calendar invitation by email.

A plain email address adds a required attendee. To add an optional attendee or book a room, pass an object with a type of required, optional or resource:

tool: create-event
params:
  subject: "Team Review"
  start: "2026-03-09T14:00:00"
  end: "2026-03-09T15:00:00"
  attendees:
    - "alice@company.com"
    - { email: "bob@company.com", type: "optional" }
    - { email: "boardroom@company.com", type: "resource" }

Preview the invitations first

Invitations go out as soon as the event is saved. Pass dryRun: true to see who would be invited without creating anything:

tool: create-event
params:
  subject: "Team Review"
  start: "2026-03-09T14:00:00"
  end: "2026-03-09T15:00:00"
  attendees: ["alice@company.com", "sam@partner.org"]
  dryRun: true

The preview starts with DRY RUN — nothing was changed. and lists each attendee, counting and marking the external ones: addresses whose domain differs from your own (read from your signed-in account). If your own address can’t be read, the external count is shown as unknown rather than guessed. Rooms and resources are listed separately.

Allowed attendees

If the server has a recipient allowlist (OUTLOOK_ALLOWED_RECIPIENTS), every attendee, rooms included, must be on it. One address that isn’t allowed refuses the whole event: nothing is created and nobody is invited, and the error lists the blocked addresses. A dryRun reports the same refusal. Each attendee must be a single plain email address. The same check applies to the attendee list you set with manage-event action=update. See Send Email Safely for what the allowlist does and doesn’t cover.

create-event also counts towards the session rate limit when one is set (OUTLOOK_MAX_CREATE_EVENT_PER_SESSION, or OUTLOOK_MAX_EMAILS_PER_SESSION); previews don’t count. A limit of 0 blocks create-event entirely (unset means no limit).

Add a Description

“Set up an offsite planning session with an agenda”

tool: create-event
params:
  subject: "Offsite Planning"
  start: "2026-03-10T10:00:00"
  end: "2026-03-10T12:00:00"
  body: "Agenda:\n1. Q2 goals review\n2. Resource planning\n3. Team feedback"

Set a Location

create-event doesn’t take a location. Create the event, then set it with manage-event, using the ID from the response:

tool: manage-event
params:
  action: "update"
  eventId: "AAMkAGR..."
  location: "Level 3 Boardroom"

Parameter Reference

ParameterWhat it doesRequired
subjectEvent titleYes
startStart time (ISO 8601)Yes
endEnd time (ISO 8601)Yes
attendeesEmail addresses (required attendees) or {email, type} objects (type: required, optional or resource)No
bodyEvent description or agendaNo
dryRunPreview who would be invited (with an external count) without creating the eventNo

Timezone Handling

Times are interpreted using the server’s configured timezone (default: Australia/Melbourne). To ensure correct scheduling:

  • Local time — omit the Z suffix: 2026-03-10T10:00:00 → interpreted as your configured timezone
  • UTC time — include the Z suffix: 2026-03-10T10:00:00Z → always UTC, converted to your timezone

Common pitfall: If your times include the Z (Zulu/UTC) suffix but you intended local time, events will be created at the wrong time. For example, 2026-03-10T10:00:00Z in Melbourne (UTC+11) would create an event at 9pm, not 10am.

Tips

  • Use plain language — your AI assistant will convert your request into the right parameters and times
  • The body field supports plain text — add agendas, links, or preparation notes
  • Check your calendar first with list-events to avoid double-booking, or use its subject filter to find the last occurrence of a meeting you’re rescheduling
  • Omit the Z suffix on times unless you specifically mean UTC
  • create-event is marked destructive because attendees are sent invitations, so clients that honour MCP annotations ask before running it. Claude Code always asks before create-event, dry runs included, because the tool carries the anthropic/requiresUserInteraction flag. Use dryRun: true to check the guest list first
  • Each create-event call sends Microsoft Graph a unique transactionId, so if a throttled request is retried, Graph recognises the repeat and doesn’t create (or send invitations for) a second copy. A separate, repeated create-event call is a new event, so check list-events before retrying one that seemed to fail
  • For finding available rooms, see Find Meeting Rooms
Was this helpful?

Related Articles