Overview
The schedule_meeting tool creates a meeting on attendees’ calendars at a specific time. Use this after finding availability or when you have a predetermined time.
{
"name": "schedule_meeting",
"description": "Schedule a meeting at a specific time. Creates calendar events for all attendees with Google Meet link. Both attendees must have connected their calendars.",
"inputSchema": {
"type": "object",
"properties": {
"attendees": {
"type": "array",
"description": "Email addresses of meeting attendees (exactly 2 required)",
"items": {
"type": "string",
"format": "email"
},
"minItems": 2,
"maxItems": 2
},
"start_time": {
"type": "string",
"format": "date-time",
"description": "Meeting start time in ISO 8601 format (e.g., '2025-01-22T14:00:00Z')"
},
"duration_minutes": {
"type": "integer",
"description": "Meeting duration in minutes",
"default": 30,
"minimum": 15,
"maximum": 480
},
"title": {
"type": "string",
"description": "Meeting title that appears on calendars",
"maxLength": 200
},
"description": {
"type": "string",
"description": "Optional meeting description or agenda",
"maxLength": 2000
},
"location": {
"type": "string",
"description": "Meeting location. Use 'Google Meet' to create video conference link.",
"default": "Google Meet"
}
},
"required": ["attendees", "start_time", "duration_minutes", "title"]
}
}
Usage in Claude Desktop
User: “Schedule a 30-minute product demo with bob@example.com on Wednesday at 2pm”
Claude will:
- Parse “Wednesday at 2pm” → ISO 8601 timestamp
- Call
schedule_meeting:
{
"attendees": ["alice@example.com", "bob@example.com"],
"start_time": "2025-01-22T14:00:00-08:00",
"duration_minutes": 30,
"title": "Product Demo",
"description": "Walkthrough of new features",
"location": "Google Meet"
}
Success Response
{
"success": true,
"meeting_id": "evt_7d8f9e3a2b1c",
"start_time": "2025-01-22T14:00:00Z",
"end_time": "2025-01-22T14:30:00Z",
"title": "Product Demo",
"attendees": ["alice@example.com", "bob@example.com"],
"location": "Google Meet",
"meet_link": "https://meet.google.com/abc-defg-hij",
"calendar_events": [
{
"user": "alice@example.com",
"event_id": "evt_google_abc123",
"calendar": "primary"
},
{
"user": "bob@example.com",
"event_id": "evt_google_def456",
"calendar": "primary"
}
]
}
Response Fields
Always true on successful scheduling
Unique Syncline meeting ID for tracking and future operations
ISO 8601 timestamp of meeting start
ISO 8601 timestamp of meeting end
Google Meet video conference URL (if location is “Google Meet”)
Details of the calendar events created for each attendee
Example Workflows
Workflow 1: Find then Schedule
// Step 1: Find availability
const availability = await mcpClient.callTool('find_mutual_availability', {
attendees: ['alice@example.com', 'bob@example.com'],
duration_minutes: 60
});
// Step 2: User picks the 2nd option
const chosenSlot = availability.slots[1];
// Step 3: Schedule at that time
const meeting = await mcpClient.callTool('schedule_meeting', {
attendees: ['alice@example.com', 'bob@example.com'],
start_time: chosenSlot.start_time,
duration_minutes: 60,
title: 'Q1 Planning Session',
description: 'Review Q1 goals and set objectives',
location: 'Google Meet'
});
console.log('Scheduled! Meeting ID:', meeting.meeting_id);
console.log('Video link:', meeting.meet_link);
Workflow 2: Direct Scheduling
// User: "Schedule lunch with bob@example.com tomorrow at noon"
// Claude knows tomorrow's date and converts noon to proper timezone
const meeting = await mcpClient.callTool('schedule_meeting', {
attendees: ['alice@example.com', 'bob@example.com'],
start_time: '2025-01-21T12:00:00-08:00', // Tomorrow at noon PST
duration_minutes: 60,
title: 'Lunch Meeting',
location: 'Cafe Venue, 123 Main St'
});
Workflow 3: Recurring Setup
// Schedule a series of weekly syncs
const dates = [
'2025-01-22T10:00:00Z',
'2025-01-29T10:00:00Z',
'2025-02-05T10:00:00Z',
'2025-02-12T10:00:00Z'
];
for (const startTime of dates) {
await mcpClient.callTool('schedule_meeting', {
attendees: ['alice@example.com', 'bob@example.com'],
start_time: startTime,
duration_minutes: 30,
title: 'Weekly Sync',
description: 'Check in on project progress'
});
}
Error Handling
User Not Connected
{
"error": "user bob@example.com not found",
"code": "USER_NOT_FOUND"
}
Solution: User needs to connect their Google Calendar.
Time Conflict
{
"error": "calendar conflict: bob@example.com has another meeting at this time",
"code": "CALENDAR_CONFLICT"
}
Solution: Use find_mutual_availability to find a free time, or confirm the user wants to double-book.
{
"error": "invalid start time: must be ISO 8601 format",
"code": "INVALID_DATE_FORMAT"
}
Solution: Use format like “2025-01-22T14:00:00Z” or “2025-01-22T14:00:00-08:00”
Past Time
{
"error": "cannot schedule meeting in the past",
"code": "INVALID_TIME"
}
Solution: Verify the timestamp is in the future.
Best Practices
1. Always Include Timezones
// Good: Explicit timezone
start_time: "2025-01-22T14:00:00-08:00" // 2pm PST
// Risky: UTC only (might not match user expectation)
start_time: "2025-01-22T22:00:00Z" // Also 2pm PST, but less clear
2. Descriptive Titles and Descriptions
// Good: Clear and actionable
{
title: "Q1 Planning: Review OKRs",
description: "Agenda:\n1. Review Q4 results\n2. Set Q1 objectives\n3. Assign owners"
}
// Bad: Vague
{
title: "Meeting",
description: ""
}
3. Validate Before Scheduling
// Check availability first
const available = await mcpClient.callTool('find_mutual_availability', {
attendees: ['alice@example.com', 'bob@example.com'],
duration_minutes: 30
});
if (available.total_found === 0) {
console.log('No availability found. Please try different times.');
return;
}
// Then schedule
const meeting = await mcpClient.callTool('schedule_meeting', {
// ... schedule at available time
});
4. Store Meeting IDs
// Save meeting ID for future reference
const meeting = await mcpClient.callTool('schedule_meeting', {
// ... meeting details
});
// Store in your database
database.saveMeeting({
syncline_meeting_id: meeting.meeting_id,
user_id: currentUser.id,
meet_link: meeting.meet_link,
scheduled_at: new Date()
});
// Later, you can use this ID to reschedule or cancel
5. Handle Google Meet Links
const meeting = await mcpClient.callTool('schedule_meeting', {
// ...
location: 'Google Meet'
});
// Send link to attendees via your app
sendNotification({
to: meeting.attendees,
subject: `${meeting.title} - Meeting Scheduled`,
body: `
Your meeting "${meeting.title}" is scheduled for ${meeting.start_time}.
Join via Google Meet: ${meeting.meet_link}
Add to calendar: The event has been added to your Google Calendar.
`
});
Meeting Locations
Google Meet (Default)
{
"location": "Google Meet"
}
Creates a video conference link automatically.
Physical Location
{
"location": "Conference Room A, 3rd Floor"
}
Other Video Services
{
"location": "Zoom: https://zoom.us/j/123456789"
}
Phone
{
"location": "Phone: +1-555-123-4567"
}
Calendar Event Details
Each scheduled meeting creates:
- Google Calendar Event on each attendee’s primary calendar
- Email Invitation sent to all attendees
- Google Meet Link (if location is “Google Meet”)
- RSVP Tracking - system tracks acceptance status
Attendees can:
- Accept/Decline the invitation (tracked by Syncline for learning)
- Propose new times (triggers reschedule workflow)
- Add notes to the event