> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getpostern.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect Microsoft

> Register your own app at Microsoft, approve one consent, and get three read-only connections: Outlook mail, calendar and contacts.

<Info>
  **Before you start**

  * **A Microsoft account** — personal, work or school. Postern reads the mail, calendar and
    contacts of the account you sign in with.
  * **Postern installed and started, with the Console open at `http://127.0.0.1:8787`.** The Console
    opens only on the machine Postern runs on. If Postern runs on a NAS or another machine, open the
    Console from your own computer over SSH first:
    [Open the Console over SSH](/start/remote-access#ssh-tunnel).
  * **About 15 minutes, in two browser tabs** — Entra in one, the Console in the other. You go back
    and forth three times. One of those moves interrupts a half-filled Entra form, so leave that tab
    open.
  * **10 uninterrupted minutes for the last step.** Postern holds the sign-in open for 10 minutes
    and cannot pause it.
</Info>

<Steps>
  <Step title="Start a new app registration" titleSize="h2" id="register">
    At [entra.microsoft.com](https://entra.microsoft.com), sign in with the account whose mail, calendar
    and contacts you want. You register your own app. Postern ships no shared one.

    The portal's masthead reads **Microsoft Entra admin center**. In the left rail, open **Entra ID**,
    then **App registrations**.

    On the **App registrations** page, an account with no apps yet shows **There are no applications
    here.** Press **+ New registration**. The registration form opens.

    In **Name**, type `Postern`. Entra's helper under that box reads "The user-facing display name for
    this application (this can be changed later)."

    Do not submit the registration form yet. The next two steps fill in the rest of it.

    <Note>
      **A dialog headed Register an application opens instead of the form.** It reads: "The ability to
      create applications outside of a directory has been deprecated. You may get a new directory by
      joining the M365 Developer Program or signing up for Azure." Its only button is **Cancel**, and
      the same words sit in an amber bar across the page. Your Microsoft account has no directory yet.
      Take **joining the M365 Developer Program** or **signing up for Azure**. Finish that sign-up. Then
      come back and press **+ New registration** again. That is expected, not a wrong turn.
    </Note>
  </Step>

  <Step title="Choose the account type that covers personal accounts" titleSize="h2" id="account-types">
    In the same form, find **Supported account types**. Entra prints "Choose the account types that can
    use this application or access this API" beneath it.

    Open the dropdown and choose this row:

    ```text theme={"system"}
    Any Entra ID Tenant + Personal Microsoft accounts
    ```

    The dropdown opens on **Single tenant only - Default Directory**. An app left on that row refuses a
    personal Outlook or Hotmail sign-in.
    [Why the default choice locks out personal accounts](/reference/provider-sign-ins#two-microsoft-registration-choices-postern-cannot-work-around)

    <Frame caption="The dropdown opens on Single tenant only - Default Directory. Take Any Entra ID Tenant + Personal Microsoft accounts.">
      <img src="https://mintcdn.com/postern/E8R3wfogdGSukifu/images/microsoft-account-types.png?fit=max&auto=format&n=E8R3wfogdGSukifu&q=85&s=5b4c433aa720c7e7553a59a1287c9276" alt="The Entra New registration form: a Name field that holds 'postern', and the Supported account types dropdown open — Single tenant only - Default Directory as the current value, then Multiple Entra ID tenants, then Any Entra ID Tenant + Personal Microsoft accounts." width="1032" height="620" data-path="images/microsoft-account-types.png" />
    </Frame>
  </Step>

  <Step title="Add the redirect URI under the desktop platform" titleSize="h2" id="redirect-uri">
    <Warning>
      Do not choose **Single-page application (SPA)**. Microsoft caps that platform's sign-in at 24
      hours, so you would sign in again every day, and no Postern setting changes that. Choose
      **Public client/native (mobile & desktop)**.
    </Warning>

    Lower in the same form, open **Select a platform** and choose **Public client/native (mobile &
    desktop)**.

    <Frame caption="Take Public client/native (mobile & desktop). Single-page application (SPA) costs you a sign-in every day.">
      <img src="https://mintcdn.com/postern/E8R3wfogdGSukifu/images/microsoft-redirect.png?fit=max&auto=format&n=E8R3wfogdGSukifu&q=85&s=ab61efac9999028424c60483e378040a" alt="The Entra platform dropdown, open, with the label 'Select a platform' and three choices beneath it: Public client/native (mobile & desktop), Web, and Single-page application (SPA)." width="512" height="294" data-path="images/microsoft-redirect.png" />
    </Frame>

    A redirect URI is the address Microsoft sends you back to after you approve. Microsoft matches it
    exactly, character for character.

    Leave the Entra tab open. In your second tab, open the Console at `http://127.0.0.1:8787`. Go to
    **Sources** → **Add a source** → **Microsoft**, the first card under **Sign in with the provider**.
    Press **Copy** beside the redirect URI. On a stock install it reads:

    ```text theme={"system"}
    http://localhost:8787/api/oauth/microsoft/callback
    ```

    The Console prints `localhost` rather than `127.0.0.1` on purpose. Microsoft's portal refuses an
    address written as an IP number over `http`. Both addresses mean the same machine. If you moved the
    Console's port, the Console prints the address that matches. Copy what the Console prints, never
    what this page prints.
    [Why the redirect URI must come from your own Console](/reference/provider-sign-ins#the-redirect-address-is-pinned-inside-postern)

    Back in Entra, paste it into the field beside the platform. Never type it.

    The platform now holds one redirect URI, which ends `/api/oauth/microsoft/callback`.
  </Step>

  <Step title="Register the app and copy the client ID" titleSize="h2" id="client-id">
    Submit the registration form. Entra registers the app and opens a page for it.

    That page shows the app's client ID. Copy it. It is the only value you carry back to the Console.
    It is 5 groups of letters and digits, separated by dashes. These zeros stand in for yours:

    ```text theme={"system"}
    00000000-0000-0000-0000-000000000000
    ```

    Change nothing else at Entra. Microsoft needs no client secret. Add no permissions by hand, and
    switch on no API. The sign-in screen in the next step is where you grant the scopes.
    [Why Microsoft needs no client secret](/reference/provider-sign-ins#what-each-provider-needs-and-why)
  </Step>

  <Step title="Paste the client ID and approve the sign-in" titleSize="h2" id="console-consent">
    Back in the Console, go to **Sources** → **Add a source** → **Microsoft**.

    Paste the client ID into the **Application (client) ID** field. Leave **Client secret** alone. The
    Console disables that box, and it reads `not required — public client (PKCE)`.

    <Frame caption="The Console's Microsoft card, captured where Microsoft is already connected, so the button reads Reconnect Microsoft. On a first run it reads Save & sign in with Microsoft, with no checkbox above it.">
      <img src="https://mintcdn.com/postern/E8R3wfogdGSukifu/images/microsoft-console-card.png?fit=max&auto=format&n=E8R3wfogdGSukifu&q=85&s=c4fa402272c59a6b7574def4805ff922" alt="The Console's Microsoft card. Left: the three registration steps and the copyable redirect URI http://localhost:8787/api/oauth/microsoft/callback, under a note that Microsoft is a public client and no secret is stored. Right: an Application (client) ID field, a disabled Client secret field that reads 'not required — public client (PKCE)', and mail, calendar and contacts chips under the line 'from this one consent'." width="1210" height="900" data-path="images/microsoft-console-card.png" />
    </Frame>

    Take the next click only when you have 10 uninterrupted minutes. Press **Save & sign in with
    Microsoft**. Microsoft takes over the tab.

    Microsoft then asks you to approve four permissions. Postern asks for `Mail.Read`,
    `Calendars.Read`, `Contacts.Read` and `offline_access` — read your mail, read your calendars, read
    your contacts, and keep the sign-in alive. Postern asks for nothing else, now or later.

    Approve all four. Microsoft returns you to the Console's **Sources** page, which now holds three
    Microsoft connections: mail, calendar and contacts.

    <Note>
      **The browser shows `{"error":"invalid or expired state"}`.** The 10 minutes ran out, or you
      already used this sign-in once. A Postern restart, or a reload of the callback address, also ends
      it. Postern stored nothing. Start again from **Sources** → **Add a source** → **Microsoft**.
    </Note>

    <Note>
      **The Console reads "Microsoft did not complete the sign-in.", with Microsoft's own code beneath
      it.** Microsoft refused the sign-in, and Postern stored nothing. Read the code, correct the
      registration at Entra, then press **Save & sign in with Microsoft** again.
    </Note>
  </Step>

  <Step title="Wait for the first sync" titleSize="h2" id="first-sync">
    On **Sources**, the three new rows read `Awaiting first sync`. That is normal. The sign-in creates
    the connections; it starts no sync.

    Postern picks up new connections within about 60 seconds. Each row then reads `Syncing…`, and then a
    `Last synced` time. Until then, an agent that asks for mail gets an empty answer, not an error.
  </Step>

  <Step title="Optional: change how far back mail goes" titleSize="h2" id="recency">
    Postern caches the last 180 days of mail. That is the **6 months** setting. To change it, go to
    **Sources** and open the Microsoft mail row. Under **Controls**, **Recency window** offers
    **3 months**, **6 months** and **12 months**. Pick one. The control appears on mail connections
    only, and Postern then re-reads the whole window from the start.
  </Step>

  <Step title="Optional: reconnect later" titleSize="h2" id="reconnect">
    To replace the app registration, or to run the consent again, go to **Sources** → **Add a source** →
    **Microsoft**. Tick **Yes — replace the stored app and re-run consent.** The button stays disabled
    until you do. Press **Reconnect Microsoft**. It replaces the stored app and never creates a second
    connection.
  </Step>
</Steps>

## Confirm it works

* In Entra, your app's platform reads **Public client/native (mobile & desktop)**, not
  **Single-page application (SPA)**.
* The Console's **Application (client) ID** field holds the same value Entra shows on your app's own
  page.
* **Sources** shows three Microsoft connections — mail, calendar and contacts — each with a
  `Last synced` time.
* The Console's **Client secret** field is empty and reads `not required — public client (PKCE)`.

## If something went wrong

| What you see                                                                      | What to do                                                                                                                                                                                                                     |
| --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| A dialog headed **Register an application** blocks the form                       | Your Microsoft account has no directory yet. Join the M365 Developer Program or sign up for Azure, then register again — [Start a new app registration](#register).                                                            |
| Microsoft asks you to sign in again every day                                     | Your app is on **Single-page application (SPA)**. In Entra, move it to **Public client/native (mobile & desktop)**, and add the redirect URI there — [Add the redirect URI under the desktop platform](#redirect-uri).         |
| Microsoft refuses the sign-in for a personal Outlook or Hotmail address           | Your app is on **Single tenant only - Default Directory**. Set **Supported account types** to **Any Entra ID Tenant + Personal Microsoft accounts** — [Choose the account type that covers personal accounts](#account-types). |
| Microsoft shows an error of its own, and the browser never returns to the Console | The registration does not hold the address Postern sends. In the Console, press **Copy** beside the redirect URI. Paste it into Entra over the old value — [Add the redirect URI under the desktop platform](#redirect-uri).   |
| `{"error":"invalid or expired state"}`                                            | The 10 minutes ran out, or you used the sign-in twice. Postern stored nothing. Start the sign-in again — [Paste the client ID and approve the sign-in](#console-consent).                                                      |
| The Console reads **Microsoft did not complete the sign-in.**                     | Microsoft refused the sign-in, and Postern stored nothing. Read Microsoft's code under that line, correct the registration, then sign in again — [Paste the client ID and approve the sign-in](#console-consent).              |
| Fewer than three connections after a consent that looked successful               | The consent granted fewer than four permissions. Press **Save & sign in with Microsoft** again and approve all four — [Paste the client ID and approve the sign-in](#console-consent).                                         |
| The three rows still read `Awaiting first sync`                                   | Postern picks up new connections within about 60 seconds. Reload **Sources** — [Wait for the first sync](#first-sync).                                                                                                         |

## What you have now

Three read-only connections out of one consent.

| Connection | What Postern stores                                                                                                                                                                                                                                          | How far back                                        |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------- |
| Mail       | Inbox and Sent — who sent it, the subject, the preview line, the dates, and the read and attachment flags. Postern never stores the message text. An agent that asks for one message pulls the body from Microsoft on demand, and Postern stores it nowhere. | 180 days; **Recency window** sets 3, 6 or 12 months |
| Calendar   | Your events                                                                                                                                                                                                                                                  | 365 days back, 365 days forward                     |
| Contacts   | Your default contacts folder                                                                                                                                                                                                                                 | all of it                                           |

* **None of the three can write.** The connector carries no actions. No agent can send mail, change
  an event, or add a contact through Postern.
* **Postern checks Microsoft every 5 minutes.** That is also the fastest it will go. **Poll cadence**
  on a connection's page only offers slower settings.
* **The app registration stays yours at Entra.** Microsoft keeps the sign-in alive as long as
  Postern uses it once every 90 days.
* **Postern never held a Microsoft password.** Revoke an agent, or disconnect Microsoft in the
  Console, and neither one can touch a password you never pasted.
  [What a grant covers](/reference/grants-and-sectors#what-a-grant-covers), and
  [what you take back when you revoke one](/reference/agent-keys#what-a-revoke-does-not-touch)

## Next

<Columns cols={2}>
  <Card title="Connect an agent" href="/start/connect-an-agent">
    Point a client at the MCP endpoint with a key you created. Local clients paste one config block;
    claude.ai and ChatGPT need a public address first.
  </Card>

  <Card title="Connect WHOOP" href="/connect/whoop">
    a WHOOP membership + a free dev app · about 10 minutes · confidential client
  </Card>
</Columns>
