Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Connect AI agents to Outlook

Scalekit connector
Open markdown

The Outlook connector lets your AI agent act in each user's Outlook account. Each user signs in to Outlook once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 126 tools.

Tools
126
What they doRead · write · destructive
50 · 57 · 1950 read57 write19 destructive
Users sign in with
OAuth app
Scalekit's or your own

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 Outlook connection

    In AgentKit > Connections, create an Outlook connection. The name you give it is the connection_name your code passes. See Configure connections.

    Scalekit credentials are available for Outlook, so you don't need to register an OAuth app. To show your own app on the consent screen, use your own credentials instead.

    Use your own OAuth app

    Register your Scalekit environment with the Outlook connector so Scalekit handles the authentication flow and token lifecycle for you. The connection name you create will be used to identify and invoke the connection programmatically. Then complete the configuration in your application as follows:

    1. Create the Outlook connection in Scalekit

      • In Scalekit dashboard, go to AgentKit > Connections > Create Connection. Search for Outlook and click Create.

        Search for Outlook and create a new connection

      • In the Configure Outlook Connection dialog, copy the Redirect URI. You will need this when registering your app in Azure.

        Copy the redirect URI from the Configure Outlook Connection dialog

    2. Register an application in Azure

      • Sign into portal.azure.com and go to Microsoft Entra ID → App registrations.

        App registrations page in Azure portal

      • Click New registration. Enter a name for your app (for example, “Scalekit Outlook Connector”).

      • Under Supported account types, select Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts.

      • Under Redirect URI, select Web and paste the redirect URI you copied from the Scalekit dashboard. Click Register.

        Paste the Scalekit redirect URI in Azure

    3. Get your client credentials

      • From the app’s Overview page, copy the Application (client) ID.

        Copy the Application (client) ID from the Azure app overview

      • Go to Certificates & secrets in the left sidebar, then click + New client secret.

        Certificates and secrets page in Azure portal

      • Enter a description (for example, “Secret for Scalekit Agent Actions”), set an expiry period, and click Add. Copy the secret Value immediately — it is only shown once.

        Add a client secret in Azure portal

    4. Add credentials in Scalekit

      • In Scalekit dashboard, go to AgentKit > Connections and open the Outlook connection you created.

      • Enter your credentials:

        • Client ID — the Application (client) ID from the Azure app overview
        • Client Secret — the secret value from Certificates & secrets
        • Scopes — select the permissions your app needs (for example, Calendars.Read, Calendars.ReadWrite, Mail.Read, Mail.ReadWrite, Mail.Send, Contacts.Read, Contacts.ReadWrite, User.Read, offline_access). See Microsoft Graph permissions reference for the full list.
      • Click Save.

  4. 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 = 'outlook'
    const identifier = 'user_123'
    // Generate an authorization link for the user
    const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
    console.log('Authorize Outlook:', 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: 'outlook_list_calendar_events',
    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
  • outlook_find_meeting_timesFind available meeting time slots for a set of attendees using Microsoft Graph's findMeetingTimes API.Read-only

    Find Meeting Times

    Find available meeting time slots for a set of attendees using Microsoft Graph's findMeetingTimes API. Returns a list of suggested meeting times when all required attendees are available within the given time window.

    Inputs

    attendee_emailsarrayrequired
    Array of attendee email addresses to check availability for. Example: ["alice@example.com", "bob@example.com"]
    end_date_timestringrequired
    End of the time window to search for meeting times, in ISO 8601 format (e.g., 2025-01-15T18:00:00). The API will not suggest slots after this time.
    meeting_durationstringrequired
    Duration of the desired meeting in ISO 8601 duration format (e.g., PT30M for 30 minutes, PT1H for 1 hour, PT1H30M for 1.5 hours).
    start_date_timestringrequired
    Start of the time window to search for meeting times, in ISO 8601 format (e.g., 2025-01-15T08:00:00). The API will look for available slots at or after this time.
    is_organizer_optionalboolean
    Whether the meeting organizer's presence is optional. When true, the organizer's calendar is not checked for availability. Defaults to false.default false
    max_candidatesinteger
    Maximum number of meeting time suggestions to return. Defaults to 20. Acceptable range: 1-40.default 20
    time_zonestring
    IANA time zone identifier for interpreting start_date_time and end_date_time (e.g., "UTC", "America/New_York", "Europe/London"). Defaults to UTC.default UTC
  • outlook_get_attachmentDownload a specific attachment from an Outlook email message by attachment ID.Read-only

    Get Attachment

    Download a specific attachment from an Outlook email message by attachment ID. Returns the full attachment including base64-encoded file content in the contentBytes field. Use List Attachments to get the attachment ID first.

    Inputs

    attachment_idstringrequired
    The ID of the attachment to download.
    message_idstringrequired
    The ID of the message containing the attachment.
  • outlook_get_calendarRetrieve a single calendar by ID, including its name, color, and owner information.Read-only

    Get Calendar

    Retrieve a single calendar by ID, including its name, color, and owner information.

    Inputs

    calendar_idstringrequired
    The unique identifier of the calendar to retrieve.
  • outlook_get_calendar_eventRetrieve an existing calendar event by ID from the user's Outlook calendar.Read-only

    Get Calendar Event

    Retrieve an existing calendar event by ID from the user's Outlook calendar.

    Inputs

    event_idstringrequired
    No description.
  • outlook_get_calendar_groupRetrieve a single calendar group by ID.Read-only

    Get Calendar Group

    Retrieve a single calendar group by ID.

    Inputs

    group_idstringrequired
    The unique ID of the calendar group to retrieve.
  • outlook_get_calendar_viewRetrieve a collection of calendar events within a specific time range from the user's primary Outlook calendar.Read-only

    Get Calendar View

    Retrieve a collection of calendar events within a specific time range from the user's primary Outlook calendar. Returns all occurrences, exceptions, and single instances of events whose start/end times fall within the specified window.

    Inputs

    endDateTimestringrequired
    End of the time range in ISO 8601 format (e.g., 2025-01-31T23:59:59). The calendar view returns events that end or overlap with this time.
    startDateTimestringrequired
    Start of the time range in ISO 8601 format (e.g., 2025-01-01T00:00:00). The calendar view returns events that start or overlap with this time.
    $filterstring
    OData filter expression to further narrow results (e.g., "subject eq 'Team Sync'").
    $orderbystring
    OData orderby expression to sort results (e.g., "start/dateTime asc").
    $selectstring
    Comma-separated list of properties to include in the response (e.g., "subject,start,end,location"). Reduces payload size.
    $topinteger
    Maximum number of events to return (1-1000). Defaults to 10 if omitted.
  • outlook_get_contactRetrieve a specific contact by ID.Read-only

    Get Contact

    Retrieve a specific contact by ID.

    Inputs

    contact_idstringrequired
    Contact ID.
    expandstring
    Expand relationships.
    selectstring
    Select properties.

    Also accepts schema_version and tool_version to pin a version.

  • outlook_get_contact_folderRetrieve a single contact folder by ID, including its display name and parent folder.Read-only

    Get Contact Folder

    Retrieve a single contact folder by ID, including its display name and parent folder.

    Inputs

    contact_folder_idstringrequired
    The ID of the contact folder to retrieve.

Workflows

Proxy API call
const result = await actions.request({
connectionName: 'outlook',
identifier: 'user_123',
path: '/v1.0/me/messages',
method: 'GET',
});
console.log(result);
Execute a tool
const result = await actions.executeTool({
connector: 'outlook',
identifier: 'user_123',
toolName: 'outlook_create_calendar_event',
toolInput: {},
});
console.log(result);