Connect Microsoft 365 (mail, calendar, OneDrive)
The Microsoft 365 connector is a preview feature. Validate it against your own account before relying on it in production.
This guide connects a Microsoft 365 account over Microsoft Graph and creates
mounts from the one connector: an Outlook mail mount, a calendar mount that
produces raisin:Event nodes, and an optional OneDrive or SharePoint files
mount. The three differ only in sync_config.resource and the mapper. For the
concepts see Virtual Nodes.
Before you start
- A running RaisinDB instance and a repository you can install packages into.
RAISIN_MASTER_KEYset on the server and backed up.RAISINDB_BASE_URLset to your public base URL.- A Microsoft 365 account with mail and a calendar.
Step 1: Install the connector
raisindb package install ms-graph-adapter --repo myapp
This deploys the adapter (/adapters/ms-graph), the mappers
/mappers/ms-graph-mail, /mappers/ms-graph-calendar, /mappers/ms-graph-files
and /mappers/ms-graph-outbox, a conflict resolver
/resolvers/ms-graph-mail, the node types msgraph:ConnectorConfig and
msgraph:ConnectionConfig, and the template /connectors/ms-graph with the
Microsoft identity endpoints and scopes preset.
Step 2: Add the connector and register an Entra app
In the admin console open Connectors, click Add connector, choose the Microsoft 365 template and save. The editor shows the OAuth Redirect URI with a copy button, and renders the template's setup instructions.
In the Azure portal under Microsoft Entra ID → App registrations:
- New registration. Choose the supported account types. The template
uses the
commonauthority; for a single-tenant app paste the Directory (tenant) ID into the connector editor's Microsoft directory (tenant) ID box and click Apply, which rewrites the endpoints. - Under Authentication add a Web redirect URI and paste the value from the connector editor.
- Under API permissions add delegated Microsoft Graph scopes. The
template requests
offline_access,openid,email,profile,Mail.Read,Mail.ReadWrite,Mail.Send,Calendars.Read,Calendars.ReadWrite,Files.Read,Files.ReadWrite,Sites.Read.All,Sites.ReadWrite.Alland their.Sharedand.Allvariants. Grant the ones you need; remove the rest from the connector's scope list before connecting so consent asks only for those. Reads need theReadscopes; the write path needsMail.ReadWrite,Mail.Send,Calendars.ReadWriteorFiles.ReadWrite. - Under Certificates & secrets create a client secret and copy its value.
- Copy the Application (client) ID.
Step 3: Connect the account
In the connector editor paste the client id and secret, enable the connector, save, and click Connect account. The account appears with its address as the subject and the scopes Microsoft granted. Microsoft does not widen an existing grant: if you add a scope later, the connections list shows it under Missing permissions and the Reconnect button re-runs consent and updates the account in place, so mounts that reference it keep working.
Each connection can carry its own settings from msgraph:ConnectionConfig:
tenant_id, resource, principal (a shared mailbox or another user),
drive_scope, site_id, drive_id and include_body. A mount's
sync_config overrides them.
Run Test connection. To test the calendar or files surface rather than
the mailbox, the mount editor's inline test forwards the mount's resource.
Step 4: Mount mail
Open Mounts, click New Mount, pick the connector and account, set
Resource to Mail, choose the mail folder with Browse (the adapter
implements browse for folders, calendars, sites and drives), and select
/mappers/ms-graph-mail. As a node:
node_type: raisin:VirtualMount
properties:
title: Outlook Inbox
integration_ref: /integrations/ms-graph
account_ref: "<connection id>"
target_workspace: default
target_branch: main
mount_path: /m365/inbox
remote_root: inbox # mail folder id; "inbox" is the default
mapping_function: /mappers/ms-graph-mail
sync_config:
resource: mail
mode: poll
interval_seconds: 300
ephemeral: true
ttl_seconds: 86400
include_body: false # true syncs body_html and body_text
include_attachments: false # true adds raisin:Asset children
enabled: true
Messages become raisin:Mail nodes with subject, from, from_address,
to, cc, bcc, reply_to, date, received_at, sent_at, snippet,
unread, is_read, importance, has_attachments, conversation_id,
message_id, folder, labels, web_url and provider: "ms-graph". Graph
has a delta feed, so after the first walk each run fetches only what changed.
For mail the adapter declares can_update with
mutable_fields: ["unread", "is_read", "importance"], so a mount with
write_config:
mode: state_only
mutable_fields: [unread, is_read, importance]
pushes read-state changes back to Outlook. Sending is a separate submit
mount with /mappers/ms-graph-outbox, whose raisin:OutboundMail commands
support send, reply, reply_all and forward.
Step 5: Mount the calendar
Set Resource to Calendar and the mapper to /mappers/ms-graph-calendar:
node_type: raisin:VirtualMount
properties:
title: Work Calendar
integration_ref: /integrations/ms-graph
account_ref: "<connection id>"
target_workspace: default
target_branch: main
mount_path: /m365/calendar
remote_root: calendar # calendar id; "calendar" is the default
mapping_function: /mappers/ms-graph-calendar
sync_config:
resource: calendar
mode: poll
interval_seconds: 300
window:
days_back: 7 # default 7
days_ahead: 30 # default 30
enabled: true
Events become raisin:Event nodes with title, ical_uid, calendar_id,
start_utc, end_utc, start_local, end_local, timezone, all_day,
recurrence_type, recurrence, status, show_as, my_response,
organizer_email, organizer_name, attendees, location,
online_meeting_url and url. raisin:Event is strict and carries the
raisin:VirtualNode mixin. The window moves with time, so the mount is a
rolling view rather than an archive. See
Sync Google Calendar
for a query over upcoming events; the shape is identical.
For the calendar the adapter declares can_create, can_update,
can_delete, supports_trash and a default delete policy of trash, and
the mapper implements to_external, so write_config.mode: mirror with a
mutable_fields list makes the node the event: edits, creates of
raisin:Event nodes named in create_node_types, and deletes propagate.
RSVPs go through a submit mount with /mappers/ms-graph-outbox and
raisin:CalendarAction commands whose action is accept, decline or
tentative.
Step 6: Mount OneDrive or SharePoint files
Set Resource to Files and the mapper to /mappers/ms-graph-files. Files
become raisin:Asset nodes with title, size, web_url, download_url,
created_at and modified_at; folders become raisin:Folder.
node_type: raisin:VirtualMount
properties:
title: OneDrive
integration_ref: /integrations/ms-graph
account_ref: "<connection id>"
target_workspace: default
target_branch: main
mount_path: /m365/files
mapping_function: /mappers/ms-graph-files
sync_config:
resource: files
drive_scope: me # me | user (with principal) | site (with site_id)
mode: poll
interval_seconds: 300
enabled: true
Leave remote_root empty for the drive root or set it to a drive item id.
For a SharePoint library set drive_scope: site and site_id; the console's
Browse lists sites and libraries. The files adapter declares
accepts_content, so a mirror mount uploads file bytes on create and on a
changed file, and its default delete policy is trash.
Real-time sync
All three surfaces support push. Set sync_config.mode to hybrid (or
webhook) and the engine registers a Graph subscription on the next run,
renews it before it expires, and removes it when the mount is disabled. This
needs RAISINDB_BASE_URL. See
Real-time sync with webhooks.
Running in production
- Each mount syncs under its own lease, so mail and calendar run independently.
- A rejected token pauses the mount with status
auth_required; Graph 429 and 503 responses are reported asrate_limitedand honourRetry-After. - A write refused for a missing scope is reported as
config_errornaming the scope, and the mount stands off before retrying the drain. - Replicated clusters need the
redislocks backend.
Next steps
- Sync Google Calendar: the same event model for Google.
- Connect Gmail: the IMAP and XOAUTH2 inbox pattern.
- Adapter reference.