Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
MS_CLIENT_IDNoLegacy Azure application (client) ID (backwards compatibility).
USE_TEST_MODENoRun with mock data instead of real API calls.false
MS_CLIENT_SECRETNoLegacy Azure client secret value (backwards compatibility).
OUTLOOK_CLIENT_IDNoYour Azure application (client) ID.
OUTLOOK_CLIENT_SECRETNoYour Azure client secret value.
OUTLOOK_ALLOWED_RECIPIENTSNoRestrict sending to approved addresses or domains via an allowlist.
OUTLOOK_MAX_EMAILS_PER_SESSIONNoConfigurable session rate limiting for sending emails (default: unlimited).

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}

Tools

Functions exposed to the LLM to take actions

NameDescription
authA

Manage authentication with the Microsoft Graph API. action=status (default) returns the current auth state, refreshing an expired access token while the refresh token is still valid (~90 days); call it first to check before other tools. action=authenticate starts sign-in: method: "device-code" (default, works headlessly) returns a code + URL for the user to visit; method: "browser" uses the local auth server on :3333 (run npm run auth-server first). force: true re-authenticates over an existing valid session. If sign-in reports that OUTLOOK_CLIENT_ID is not configured, ask the user for their Azure Application (client) ID and pass it as clientId. action=device-code-complete finishes device-code sign-in once the browser shows it succeeded. action=about returns server version, configured audience, scope list and other diagnostics. Tokens persist to ~/.outlook-assistant-tokens.json and survive server restarts.

list-eventsA

List calendar events for the signed-in user (read-only). By default returns upcoming events (start ≥ now). Optional startAfter, startBefore and subject filters find past, current or specifically-named events; supplying any of them replaces the default "now" lower bound and the filters are AND-ed together. Results are oldest first, except when the search only looks backwards (startBefore without startAfter, or subject alone), where they are newest first. Each event shows its subject, location, start/end, a body preview and its id. Use count (default 10, max 100) to control page size. Each start/end is returned as a canonical UTC ISO-8601 instant (e.g. 2026-04-02T22:00:00.000Z) followed by a labelled local rendering in the configured display timezone (default Australia/Melbourne; override with OUTLOOK_DEFAULT_TIMEZONE) — the UTC value is authoritative, so consumers never have to guess the zone.

create-eventA

Create a new calendar event on the signed-in user's default calendar. Returns the created event with its id, webLink, and (if attendees are present) an auto-generated online-meeting URL — attendees receive invitations on save, so pass dryRun: true first to preview who would be invited (and how many are external) without creating anything. When OUTLOOK_ALLOWED_RECIPIENTS is set, every attendee must be allowed or nothing is created. Times use the configured timezone (default Australia/Melbourne; override with OUTLOOK_DEFAULT_TIMEZONE); omit the Z suffix to send local time. Use manage-event action=update to modify an event after creation, or manage-event action=cancel/delete to remove it. Real creates count against the session limit (OUTLOOK_MAX_CREATE_EVENT_PER_SESSION, else OUTLOOK_MAX_EMAILS_PER_SESSION); 0 refuses every create.

manage-eventA

Manage an existing calendar event. dryRun: true previews any action without changing or sending anything: who would be emailed, with an external count (update also: who is added or removed, and the PATCH body). action=update edits fields via PATCH (subject, start, end, attendees, body, location, isOnlineMeeting, sensitivity, showAs, importance, categories, reminderMinutesBeforeStart); only fields you pass change. action=decline declines an invitation (optional comment; sendResponse: false declines without notifying the organiser). action=cancel cancels an event you organised and emails attendees. action=delete removes the event from your calendar (Graph documents no guaranteed recovery); deleting a meeting you organised that has attendees still emails them a cancellation, so use cancel with a comment to control that message. Returns the updated event on update; a confirmation otherwise. There is no accept action: accept invitations in the Outlook UI, as Graph's accept verb is unreliable.

search-emailsA

Search, list, delta-sync or thread-group emails (read-only); parameters set the mode. No params: recent emails in folder (default inbox). query/from/to/subject/date filters: search, combined as an OData filter. searchExpression (deprecated alias kqlQuery): a raw Graph $search expression. deltaMode: true: current state plus a deltaToken to pass back next time for changes only. groupByConversation: true: conversation threads. conversationId: every message in one thread. internetMessageId: the message with that RFC Message-ID. sharedMailbox (alias email) searches a shared/delegated mailbox, custom folders and nested paths included. Personal Outlook.com accounts have limited $search, so the tool falls back to OData filters and a recent listing automatically; structured filters (from/subject/receivedAfter/hasAttachments/unreadOnly) give cleaner results there. Returns up to count messages (id/subject/from/receivedDateTime/preview); outputVerbosity expands them.

read-emailA

Read a single email by id (read-only). Returns subject, from/to/cc, date and the body as Markdown (HTML stripped to text): up to 2,000 characters by default, up to 40,000 with outputVerbosity: full; a cut body ends with a note on how to get the rest. With headersMode: true: returns RFC-822 forensic headers in place of the body (DKIM, SPF, DMARC, Received chain, Message-ID, Authentication-Results) — importantOnly: true for the security-relevant subset, groupByType: true for a category-bucketed view, raw: true for JSON. With includeHeaders: true (non-headers-mode): adds basic headers alongside the body. If the id came from a shared/delegated mailbox (e.g. via search-emails or access-shared-mailbox with sharedMailbox set), you MUST pass the same sharedMailbox (or alias email) here — message IDs are mailbox-scoped, and reading a shared-mailbox id without it fails with 404 ErrorInvalidMailboxItemId.

send-emailA

Compose and send an email immediately (destructive: sends external comms). Returns a confirmation. Safety controls: dryRun: true returns the composed message for review without sending; checkRecipients: true runs get-mail-tips first and returns its warnings. If the tips show an out-of-office reply, a full mailbox, a delivery restriction or external recipients, the send is refused until repeated with acknowledgeWarnings: true. Personal Outlook.com accounts return no tips, and no warnings is not proof of delivery. Subject to the session limit (OUTLOOK_MAX_SEND_EMAIL_PER_SESSION, else OUTLOOK_MAX_EMAILS_PER_SESSION; 0 refuses every send) and recipient allowlist (OUTLOOK_ALLOWED_RECIPIENTS) when configured; both refuse before any Graph request. For a review-before-send workflow, use draft (action=create → update → send); a draft can be checked in Outlook before it goes. Comma-separated recipient strings or arrays both accepted.

draftA

Draft lifecycle for review-before-send workflows (destructive: covers send and delete). action=create saves a new draft and returns its id (dryRun: true previews without saving; checkRecipients: true runs mail-tips first). action=update patches a draft by id (only fields passed change). action=send sends a draft and counts against the send-email session limit (0 refuses every send). action=delete moves a draft to Recoverable Items (restorable for a limited time). update/send/delete refuse any id that is not an unsent draft. action=reply/reply-all creates a reply draft from a message id (comment prepends text; not with body). action=forward creates a forward draft (needs id and to). The recipient allowlist (OUTLOOK_ALLOWED_RECIPIENTS) applies to create/update/forward, to the draft's current to/cc/bcc on send, and to reply/reply-all, whose draft is deleted if a recipient is not allowed. Returns the draft on create/update/reply/forward; a status on send/delete.

update-emailA

Update message state without modifying content (idempotent — safe to retry). action=mark-read/mark-unread sets isRead on a single message by id. action=flag sets a follow-up flag with optional dueDateTime/startDateTime: ISO 8601 with a time, kept as that exact instant when it has Z or a ±hh:mm offset and read in OUTLOOK_DEFAULT_TIMEZONE when it has none; date-only or unparseable values are refused before any change. With only dueDateTime, the start is 09:00 on the due date, or the due time if earlier. action=unflag clears the flag; action=complete marks it done. Flag/unflag/complete take id (single) or ids (batch, updated one at a time: one PATCH each, not Graph $batch). sharedMailbox (alias email) updates messages in a shared/delegated mailbox (default: the signed-in account; needs Mail.ReadWrite.Shared and delegate access). Returns a status per message.

attachmentsA

Inspect or retrieve email attachments. action=list (default) returns metadata for all attachments on messageId (id, name, contentType, size, isInline) — read-only. action=view returns inline content for text/JSON/XML attachments via attachmentId; binary types require download. action=download saves the attachment under a new, unique name in outputDir (default system temp directory, auto-created; must be inside the temp directory, ~/Downloads, ~/Documents or OUTLOOK_EXPORT_DIR) and returns the saved file path. messageId is required for all actions; attachmentId is required for view/download. If messageId came from a shared/delegated mailbox, pass the same sharedMailbox (or alias email) — attachment IDs are scoped to the message and fail under /me otherwise. Use outputVerbosity to control list field count.

exportA

Export emails to files. target=message (default) exports one email by id (mime/eml/markdown/json/csv) to savePath: a directory (or a path ending in /, created if missing) gets a new, unique file name; a file path is created new and an existing file is replaced only with overwrite: true. target=messages batch-exports emailIds, or matches for searchQuery/query, into outputDir, at most 100 messages per call. target=conversation exports a thread (up to 1000 messages) by conversationId into outputDir (eml/mbox/markdown/json/html/csv; order: "reverse" for newest first). target=mime returns raw RFC-822 MIME for id (headersOnly, base64, maxSize, default 1MB). Files are written only inside the system temp directory (the default), ~/Downloads, ~/Documents or OUTLOOK_EXPORT_DIR, never to dot-prefixed names. Pass sharedMailbox (alias email) when the ids come from a shared mailbox. includeAttachments defaults to true for one message, false for batch.

get-mail-tipsA

Pre-send recipient validation via Graph POST /me/getMailTips (read-only; uses the existing Mail.Read scope — no extra permissions). Returns per-recipient tips covering automatic replies (out-of-office), mailbox full status, custom admin mail tips, delivery restrictions, moderation requirements, external-vs-internal scope, max message size, and group member counts (total + external). Use ahead of send-email or draft action=create to catch issues like OOO replies or external-recipient warnings before the message goes out; send-email/draft accept checkRecipients: true to invoke this automatically. Accepts either a comma-separated string or an array of addresses; tipTypes filters which tips are requested (defaults to all).

foldersA

Manage mail folders. Address a folder by name, by slash-separated path for nested folders (e.g. Inbox/Clients/Acme, case-insensitive) or by ID; a bare name matches a unique top-level folder first, then nested ones (an ambiguous name returns the candidates). action=list (default) returns the tree with each folder's path and id (includeItemCounts, includeChildren). action=create makes name under the root or parentFolder/parentFolderId. action=move moves emailIds into targetFolder/targetFolderId. action=stats returns total/unread counts for folder or folderId. action=delete removes a folder (folderName/path or folderId) with everything in it, subfolders included. It skips Deleted Items and Graph documents no restore path, so pass dryRun: true first to see what would be lost. Protected folders (Inbox, Sent Items, etc.) can't be deleted. Every action accepts sharedMailbox (alias email) to work in a shared or delegated mailbox (default: your own).

manage-rulesA

Server-side inbox rules (destructive: covers delete; dryRun previews create/update). Rules run on the Exchange server whichever client is open. action=list (default) returns rules with id/name/sequence; includeDetails: true adds conditions/actions/exceptions. action=create builds a rule from condition params (12, e.g. fromAddresses, containsSubject, bodyContains, hasAttachments, importance, sensitivity), action params (9, e.g. moveToFolder/copyToFolder — folder name, nested path like Triage/Delete, or ID — forwardTo, redirectTo, assignCategories, markAsRead, delete) and optional except* exceptions. action=update patches fields by ruleId or ruleName. action=reorder changes priority via sequence (lower runs first). action=delete removes a rule. The recipient allowlist applies to forwardTo/redirectTo. There is no permanentDelete action. Changes count against the session limit (OUTLOOK_MAX_MANAGE_RULES_PER_SESSION, else OUTLOOK_MAX_EMAILS_PER_SESSION); 0 refuses them.

manage-contactA

Full CRUD over the signed-in user's personal Outlook contacts (destructive: covers delete action). action=list (default) returns contacts with pagination via skip/count (default 50). action=search returns contacts matching query against name/email (default 25). action=get returns full contact detail by id. action=create adds a new contact and returns its id. action=update patches the given fields by id (only fields passed are changed). action=delete removes the contact by id; it skips Deleted Items, so treat it as permanent and pass dryRun: true first to confirm which contact it is. Use outputVerbosity (minimal/standard/full) on list/search to control field count. Searches only your personal contact store; for relevance-ranked search across contacts, the directory and recent communications, use search-people.

search-peopleA

Relevance-ranked search across personal contacts, organisation directory, and recent communications via the Microsoft Graph People API (read-only). Returns people objects with displayName, emailAddresses, companyName, jobTitle, and relevance metadata, for "who is X?" or "who do I email about Y?" lookups. For entries from your personal contact store only, use manage-contact action=search.

manage-categoryA

Manage the user's master category list (the colour-coded labels available across mail/calendar/contacts). action=list (default) returns categories with id/displayName/color. action=create adds a new category — displayName required, color optional (preset0-preset24, e.g. preset0=Red, preset7=Blue). action=update (alias set — deprecated) changes name/colour by id. action=delete removes a category — this does NOT untag messages already labelled with it; existing messages retain the orphaned label until manually cleaned. Use apply-category to tag/untag specific messages.

apply-categoryA

Tag or untag email messages with master categories (those created via manage-category). action=set (default) replaces the message's category set with the supplied categories array. action=add appends categories to whatever's already on the message. action=remove removes only the named categories, leaving the rest. Accepts either messageId (single) or messageIds (batch: one request per message). categories are matched by display name — names must already exist in the target mailbox's master list. For your own mailbox, create them via manage-category first; for a shared mailbox, the names must already exist there (manage-category only manages the signed-in account's master list). Pass sharedMailbox (or alias email) to categorise messages in a shared/delegated mailbox (default: the signed-in account; requires Mail.ReadWrite.Shared + delegate access). Returns per-message confirmation.

manage-focused-inboxA

Manage Focused Inbox sender overrides — explicit rules that force messages from a given sender into Focused or Other regardless of the ML classifier. action=list (default) returns existing overrides with id/sender/classifyAs. action=set creates or updates an override for emailAddress (optional name), routing future mail to focused (default) or other. action=delete removes the override for emailAddress. Note: this only works on accounts that have Focused Inbox enabled — personal Outlook.com accounts without it return an empty list.

mailbox-settingsA

Read or update mailbox-level settings (idempotent — safe to retry; sets are PATCH-style and merge with existing state). action=get (default) returns settings — use section to filter (language, timeZone, workingHours, automaticRepliesSetting, or all). action=set-auto-replies configures out-of-office: enabled true/false, optional startDateTime/endDateTime (ISO 8601) for scheduled mode, internalReplyMessage and (optionally) externalReplyMessage and externalAudience (none/contactsOnly/all); pass dryRun: true to preview who would get replies without changing anything. action=set-working-hours updates the schedule: startTime/endTime (HH:MM) and daysOfWeek (array of monday..sunday). Returns the updated settings object on set actions.

access-shared-mailboxA

List emails or folders in a shared mailbox the signed-in user can access (read-only). Returns messages from sharedMailbox (alias email) and folder (default inbox) with id/subject/from/receivedDateTime/preview, the same shape as search-emails list mode. folder takes a well-known name (inbox, sent, archive…), a custom/localized display name (e.g. Archiv), a nested path (e.g. Inbox/Vendors/Acme), or pass a raw folderId. listFolders: true enumerates the shared mailbox's folder tree (names, paths, IDs, counts), to find custom subfolders before reading them. Needs the mailbox delegated to the signed-in user in Exchange (admin-configured). outputVerbosity sets field count and count (default 25, max 50) page size. For search and filters over a shared mailbox, use search-emails with sharedMailbox set. Custom/localized names, nested paths and listFolders need the server opt-in setting OUTLOOK_SHARED_MAILBOX (work/school only); without it folder must be a well-known name or a folder ID.

find-meeting-roomsA

Discover bookable meeting rooms in the user's organisation via the Graph rooms endpoint (read-only). Returns room resources with displayName, emailAddress, building, floor, capacity, and bookingType — suitable for piping into create-event as attendees. Filter by query (matches name/email), building, floor, or minimum capacity. Returns empty list on personal accounts (the rooms endpoint is M365-only). Use outputVerbosity to control field count.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A4.2/5.0

Scored across 22 tools

Disambiguation4/5

Each tool targets a fairly distinct resource+action (email read/search/send, calendar, contacts, rules, categories, settings). Minor overlap exists between search-emails and access-shared-mailbox (both list emails, and search-emails also accepts sharedMailbox), and between manage-contact search and search-people, but descriptions clearly demarcate them.

Naming Consistency3/5

Most names are snake_case verb_noun (search-emails, create-event, manage-rules, apply-category), but several are bare nouns (auth, draft, attachments, export, folders), mixing conventions. Still readable, but not a single predictable pattern.

Tool Count4/5

22 tools is on the heavier side but justified by a genuinely broad domain spanning mail, calendar, contacts, categories, rules, settings and shared mailboxes. Each tool earns its place with clear scope; none appears redundant.

Completeness4/5

Very thorough lifecycle coverage: search/read/send/draft/update, attachments, export, folders, rules, contacts CRUD, categories, focused inbox, settings, shared mailboxes and rooms. Minor gaps: no direct delete-message tool and no event-accept action (noted as a Graph limitation), but core workflows are covered.

Maintenance

ActivityMaintained
ResponsivenessResponsive