Skip to main content

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.

Tool Schema

{
  "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:
  1. Parse “Wednesday at 2pm” → ISO 8601 timestamp
  2. 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"
}

Response Format

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

success
boolean
Always true on successful scheduling
meeting_id
string
Unique Syncline meeting ID for tracking and future operations
start_time
string
ISO 8601 timestamp of meeting start
end_time
string
ISO 8601 timestamp of meeting end
Google Meet video conference URL (if location is “Google Meet”)
calendar_events
array
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.

Invalid Time Format

{
  "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
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