Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Connect AI agents to the Cal MCP server

Vendor MCP
Open markdown

The Cal MCP connector routes your AI agent's tool calls to Cal's own MCP server through Scalekit. Each user signs in to Cal once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 35 tools.

Tools
35
What they doRead · write · destructive
18 · 13 · 418 read13 write4 destructive
Users sign in with
OAuth app
Your own Cal MCP server app

What you can do

  • Manage bookings: create, confirm, reschedule, and cancel bookings, and add attendees or mark no-shows
  • Check availability: find open time slots for a host and read busy times from connected calendars
  • Manage event types: create, update, and delete the meeting types people can book
  • Set working hours: create, update, and delete availability schedules, including the default schedule
  • Manage organizations: add, update, and remove organization members, and read routing forms and their responses

Setup

  1. Install the SDK

    Terminal window
    npm install @scalekit-sdk/node dotenv
  2. Set your credentials

    Add your Scalekit credentials to your .env file. Find values in app.scalekit.com > Developers > API Credentials.

    .env
    SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
    SCALEKIT_CLIENT_ID=<your-client-id>
    SCALEKIT_CLIENT_SECRET=<your-client-secret>
  3. Create the Cal MCP connection

    In AgentKit > Connections, create a Cal MCP connection and copy its redirect URI. The name you give it is the connection_name your code passes. See Configure connections.

  4. Register an OAuth app

    Cal MCP server connections use your own OAuth app. Register one with Cal MCP server and add the redirect URI you copied.

    Then enter the app's Client ID and Client Secret on the Cal MCP connection.

  5. Authorize a user and make your first call

    quickstart.mts
    import { ScalekitClient } from '@scalekit-sdk/node'
    import 'dotenv/config'
    import { createInterface } from 'node:readline/promises'
    const scalekit = new ScalekitClient(
    process.env.SCALEKIT_ENVIRONMENT_URL,
    process.env.SCALEKIT_CLIENT_ID,
    process.env.SCALEKIT_CLIENT_SECRET,
    )
    const actions = scalekit.actions
    const connector = 'calmcp'
    const identifier = 'user_123'
    // Generate an authorization link for the user
    const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
    console.log('Authorize Cal MCP:', link)
    const rl = createInterface({ input: process.stdin, output: process.stdout })
    await rl.question('Press Enter after authorizing...')
    rl.close()
    // Make your first call
    const result = await actions.executeTool({
    connector,
    identifier,
    toolName: 'calmcp_get_me',
    toolInput: {},
    })
    console.log(result)
    Terminal window
    npx tsx quickstart.mts

    Each user signs in once. See Authorize a user for the full flow and statuses.

Tools

Pass the exact name to execute_tool
Try in PlaygroundRequest a tool
  • calmcp_get_availabilityGet available time slots for a host.Read-only

    Get Availability

    Get available time slots for a host. You MUST provide at least one identifier: (1) eventTypeId, (2) eventTypeSlug + username, (3) eventTypeSlug + teamSlug, or (4) usernames (comma-separated, min 2, for dynamic events). 'username' is the host whose availability you are checking. Start/end must be in UTC ISO 8601.

    Inputs

    endstringrequired
    Range end in UTC, ISO 8601 (e.g. '2024-08-14' or '2024-08-14T18:00:00Z')
    startstringrequired
    Range start in UTC, ISO 8601 (e.g. '2024-08-13' or '2024-08-13T09:00:00Z')
    bookingUidToReschedulestring
    Booking UID being rescheduled — ensures original time appears in available slots
    durationinteger
    Desired slot duration in minutes (for variable-duration or dynamic events, defaults to 30)
    eventTypeIdinteger
    Event type ID. Use this OR (eventTypeSlug + username) OR (eventTypeSlug + teamSlug).
    eventTypeSlugstring
    Event type slug. Must be combined with username (individual) or teamSlug (team).
    formatstring
    Response format: 'range' (start+end) or 'time' (start only)
    organizationSlugstring
    Organization slug, needed when the user/team is within an organization.
    teamSlugstring
    Team slug. Required with eventTypeSlug for team event types.
    timeZonestring
    IANA time zone for returned slots (e.g. America/New_York). Defaults to UTC.
    usernamestring
    Username of the host whose availability you are checking. Required with eventTypeSlug for individual event types.
    usernamesstring
    Comma-separated or array of usernames for dynamic events (min 2). organizationSlug is needed only if users belong to an org.
  • calmcp_get_bookingGet a specific booking by its UID (use get_bookings to find UIDs).Read-only

    Get Booking

    Get a specific booking by its UID (use get_bookings to find UIDs). Returns full details including attendees, location, and metadata.

    Inputs

    bookingUidstringrequired
    Booking UID
  • calmcp_get_booking_attendeeGet a specific attendee by their numeric ID within a booking.Read-only

    Get Booking Attendee

    Get a specific attendee by their numeric ID within a booking. Use get_booking_attendees to find attendee IDs.

    Inputs

    attendeeIdintegerrequired
    Attendee ID. Use get_booking_attendees to find this.
    bookingUidstringrequired
    Booking UID
  • calmcp_get_booking_attendeesGet all attendees for a booking by its UID.Read-only

    Get Booking Attendees

    Get all attendees for a booking by its UID.

    Inputs

    bookingUidstringrequired
    Booking UID
  • calmcp_get_bookingsList bookings with pagination (default 100, max 250 per page — use take/skip for more).Read-only

    Get Bookings

    List bookings with pagination (default 100, max 250 per page — use take/skip for more). Supports filtering by status (upcoming, recurring, past, cancelled, unconfirmed), attendee email/name, event type, team, date ranges (afterStart, beforeEnd), and sorting (sortStart, sortEnd, sortCreated).

    Inputs

    afterCreatedAtstring
    Filter bookings created after this ISO 8601 date
    afterStartstring
    Filter bookings starting after this ISO 8601 date
    afterUpdatedAtstring
    Filter bookings updated after this ISO 8601 date
    attendeeEmailstring
    Filter by attendee email
    attendeeNamestring
    Filter by attendee name
    beforeCreatedAtstring
    Filter bookings created before this ISO 8601 date
    beforeEndstring
    Filter bookings ending before this ISO 8601 date
    beforeUpdatedAtstring
    Filter bookings updated before this ISO 8601 date
    bookingUidstring
    Filter by booking UID
    eventTypeIdinteger
    Filter by event type ID
    eventTypeIdsstring
    Comma-separated event type IDs (e.g. '100,200')
    skipinteger
    Results to skip (offset)
    sortCreatedstring
    Sort by creation timeone of ascdesc
    sortEndstring
    Sort by end timeone of ascdesc
    sortStartstring
    Sort by start timeone of ascdesc
    sortUpdatedAtstring
    Sort by updated timeone of ascdesc
    statusstring
    Comma-separated statuses: upcoming, recurring, past, cancelled, unconfirmed
    takeinteger
    Max results to return (default 100, max 250)
    teamIdinteger
    Filter by team ID
    teamsIdsstring
    Comma-separated team IDs (e.g. '50,60')
  • calmcp_get_busy_timesGet busy/blocked time blocks from a connected calendar (e.g.Read-only

    Get Busy Times

    Get busy/blocked time blocks from a connected calendar (e.g. Google Calendar) between two dates. Returns a list of time ranges when the user is unavailable. Required: dateFrom, dateTo (YYYY-MM-DD), credentialId, and externalId. WORKFLOW: (1) Call get_connected_calendars first to get the real credentialId (number) and externalId (e.g. email) for the calendar — NEVER guess or fabricate these. (2) Provide dateFrom and dateTo as YYYY-MM-DD strings. (3) Optionally pass timeZone (IANA, e.g. 'America/New_York') to localise the results.

    Inputs

    credentialIdnumberrequired
    The credential ID of the calendar integration. Use get_connected_calendars to obtain this — never guess.
    dateFromstringrequired
    Start date for the query (e.g. '2024-08-13'). Required.
    dateTostringrequired
    End date for the query (e.g. '2024-08-14'). Required.
    externalIdstringrequired
    The external calendar ID (e.g. the email address for Google Calendar). Use get_connected_calendars to obtain this — never guess.
    loggedInUsersTzstring
    IANA time zone of the logged-in user (e.g. 'America/New_York'). Used to interpret date boundaries.
    timeZonestring
    IANA time zone for the query (e.g. 'America/New_York'). Defaults to UTC.
  • calmcp_get_conferencing_appsList all conferencing applications connected to the authenticated user's account (e.g.Read-only

    Get Conferencing Apps

    List all conferencing applications connected to the authenticated user's account (e.g. Zoom, Google Meet, Cal Video).

    Inputs

    This tool takes no inputs.

  • calmcp_get_connected_calendarsList all calendar integrations connected to the authenticated user's account.Read-only

    Get Connected Calendars

    List all calendar integrations connected to the authenticated user's account. Returns each calendar's credentialId and externalId, which are required by get_busy_times. Also shows the user's destination calendar.

    Inputs

    This tool takes no inputs.