Skip to main content
Microsoft OAuth uses PKCE flow (Proof Key for Code Exchange) with a public client. No client secret is required for desktop applications.

Overview

Craft Agents integrates with Microsoft 365 services using Azure AD OAuth 2.0. Supports both personal Microsoft accounts and work/school accounts (Azure AD) through the “common” tenant endpoint. Supported Services:
  • Outlook: Email, contacts, calendar events
  • OneDrive: File storage and sharing
  • Microsoft Calendar: Event management
  • Teams: Chat, channels, messages
  • SharePoint: Site and document access

Prerequisites

  • A Microsoft account (personal or work/school)
  • Access to Azure Portal
  • 10 minutes for initial setup

Complete Setup Guide

1

Create Azure App Registration

  1. Go to Azure Portal
  2. Search for Azure Active Directory (or Microsoft Entra ID)
  3. Click App registrations in left sidebar
  4. Click New registration
Configure your app:
  • Name: e.g., “Craft Agent Desktop”
  • Supported account types:
    • Choose Accounts in any organizational directory and personal Microsoft accounts
    • This supports both work/school and personal accounts
  • Redirect URI: Leave blank (add in next step)
  1. Click Register
  2. Note your Application (client) ID — you’ll need this
2

Add Mobile and Desktop Platform

  1. In your app registration, click Authentication in left sidebar
  2. Click Add a platform
  3. Select Mobile and desktop applications
  4. Check https://login.microsoftonline.com/common/oauth2/nativeclient
  5. Add custom redirect URI: http://localhost/callback
    • This allows the OAuth callback to work on any local port
  6. Click Configure
PKCE flow is automatically used for mobile and desktop applications. No client secret is needed.
3

Configure API Permissions

  1. Click API permissions in left sidebar
  2. Click Add a permission
  3. Select Microsoft Graph
  4. Choose Delegated permissions (not Application permissions)
Add permissions based on your needs:
  • Mail.ReadWrite - Read and write email
  • Mail.Send - Send email
  • User.Read - Sign in and read user profile
  • Calendars.ReadWrite - Manage calendar events
  • User.Read - Sign in and read user profile
  • Files.ReadWrite - Read and write files
  • User.Read - Sign in and read user profile
  • Chat.ReadWrite - Read and send chat messages
  • ChannelMessage.Send - Send messages to channels
  • User.Read - Sign in and read user profile
  • Sites.ReadWrite.All - Read and write site collections
  • User.Read - Sign in and read user profile
  1. Click Add permissions
  2. Permissions are granted on first user login (no admin consent needed for delegated permissions)
offline_access is automatically included by Craft Agent to request refresh tokens.
4

Set Environment Variable

Add your Microsoft Client ID to your .env file:
.env
MICROSOFT_OAUTH_CLIENT_ID=your-client-id-here
No client secret required! PKCE flow uses code challenges instead of static secrets for security.
5

Rebuild Craft Agents (if building from source)

If you’re building from source:
bun install
bun run electron:start
The Microsoft Client ID is baked into the build at compile time.

OAuth Flow

1

Initiate Authentication

Tell the agent:
Connect to my Outlook account
or
Connect to OneDrive
2

Browser Opens

  1. Microsoft login page opens
  2. Sign in with your Microsoft account
  3. Choose account (personal or work/school)
3

Grant Permissions

  1. Review requested permissions
  2. Click Accept to authorize
  3. Browser redirects to callback URL
4

Token Exchange

  1. Craft Agent receives authorization code
  2. Exchanges code for access token using PKCE verifier
  3. Tokens stored encrypted in ~/.craft-agent/credentials.enc

PKCE Security Flow

Microsoft OAuth uses PKCE (Proof Key for Code Exchange) for enhanced security:
  1. Generate code verifier: Random 32-byte string (base64url encoded)
  2. Create code challenge: SHA-256 hash of verifier (base64url encoded)
  3. Authorization request: Send challenge to Microsoft
  4. Token exchange: Send verifier to prove you initiated the request
PKCE eliminates the need for a client secret, making it ideal for desktop and mobile apps where secrets can’t be securely stored.

Scopes by Service

[
  'https://graph.microsoft.com/Mail.ReadWrite',
  'https://graph.microsoft.com/Mail.Send',
  'https://graph.microsoft.com/User.Read',
  'offline_access'
]
Access email, send messages, read user profile.
[
  'https://graph.microsoft.com/Calendars.ReadWrite',
  'https://graph.microsoft.com/User.Read',
  'offline_access'
]
Manage calendar events and appointments.
[
  'https://graph.microsoft.com/Files.ReadWrite',
  'https://graph.microsoft.com/User.Read',
  'offline_access'
]
Access and manage files in OneDrive.
[
  'https://graph.microsoft.com/Chat.ReadWrite',
  'https://graph.microsoft.com/ChannelMessage.Send',
  'https://graph.microsoft.com/User.Read',
  'offline_access'
]
Send messages and access Teams chat.
[
  'https://graph.microsoft.com/Sites.ReadWrite.All',
  'https://graph.microsoft.com/User.Read',
  'offline_access'
]
Access SharePoint sites and documents.
offline_access is required to receive a refresh token for long-term access.

Token Refresh

Microsoft access tokens expire after 1 hour. Craft Agent automatically refreshes them:
  • Access token lifespan: 1 hour
  • Refresh token lifespan: 90 days (rolling)
  • Automatic refresh: Before each API call if token expired
  • Token rotation: Microsoft may issue new refresh tokens
Refresh token expiration: If not used for 90 days, the refresh token expires. Users must re-authenticate.

Multi-Tenant Support

Craft Agent uses the common tenant endpoint:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize
This supports:
  • Personal Microsoft accounts (Outlook.com, Hotmail, Live)
  • Work/school accounts (Azure AD, Microsoft 365)
  • Multi-tenant Azure AD apps
For single-tenant (organization-only) apps, replace common with your tenant ID in Azure app configuration.

Source Configuration

Example config.json for a Microsoft source:
Outlook
{
  "name": "Outlook",
  "type": "api",
  "api": {
    "microsoftService": "outlook"
  }
}
OneDrive
{
  "name": "OneDrive",
  "type": "api",
  "api": {
    "microsoftService": "onedrive"
  }
}
Teams
{
  "name": "Microsoft Teams",
  "type": "api",
  "api": {
    "microsoftService": "teams"
  }
}

Security Best Practices

  • Encrypted storage: Tokens stored in ~/.craft-agent/credentials.enc (AES-256-GCM)
  • PKCE flow: No static client secret to compromise
  • CSRF protection: State parameter prevents cross-site attacks
  • Scope minimization: Only request permissions you need
  • Token expiration: Access tokens expire after 1 hour
  • Refresh token rotation: Microsoft may rotate refresh tokens for security

Troubleshooting

Client ID is missing:
  1. Verify MICROSOFT_OAUTH_CLIENT_ID environment variable is set
  2. Rebuild Craft Agents after setting the env var
  3. Check .env file is in the project root
The redirect URI doesn’t match Azure app configuration:
  1. Go to Authentication in your Azure app registration
  2. Ensure Mobile and desktop applications platform is added
  3. Verify http://localhost/callback is listed
  4. Save and try again
CSRF protection triggered:
  1. Check system time is correct
  2. Clear browser cache
  3. Close other OAuth flows
  4. Try again
Refresh token might be expired or revoked:
  1. Re-authenticate to get a new refresh token
  2. Ensure offline_access scope is included (automatic)
  3. Check refresh token hasn’t expired (90-day limit)
  4. Verify app hasn’t been revoked in Microsoft account settings
Access token doesn’t have User.Read permission:
  1. Go to API permissions in Azure app registration
  2. Verify User.Read is added
  3. Re-authenticate to grant new permissions

Example Usage

Once connected, you can interact with Microsoft services:
Show me my last 10 emails from Outlook
Create a calendar event for tomorrow at 2pm: "Team Meeting"
Upload report.pdf to my OneDrive
List all files in my OneDrive Documents folder
Send a Teams message to the #general channel

Build docs developers (and LLMs) love