copilot-outlook-connector
Outlook.com personal connector
A local, reusable TypeScript STDIO MCP server for personal Microsoft accounts such as Outlook.com and Hotmail. Each account has an independent delegated grant and secure credential namespace. This is not an organizational Microsoft 365 connector, an app-only integration, a dashboard, or a native Copilot connector manifest.
Capabilities and boundaries
Area | Included | Intentionally absent |
Structured search/list, message and paginated conversation reads, attachment metadata and bounded inert file bytes, unsent new/reply/reply-all drafts | Send, forwarding, move/archive/delete, categories, arbitrary MIME or header injection | |
Calendar | Discovery, event and instance reads, event creation/updates/deletion, attendee invitations, self-RSVP, whole-series and exact-occurrence operations | Calendar creation/deletion, sharing/ACL changes, contacts, this-and-following series splitting |
Availability | CalendarView-derived busy/common availability for explicitly selected accessible account/calendar sources | Organizational getSchedule/findMeetingTimes, arbitrary people-directory availability |
Safety | Durable request receipts, explicit accounts, OS credential storage, generation checks, human WebAuthn approvals | Agent |
This is not unrestricted Outlook parity. Search is structured Graph filtering, not Gmail syntax or a full-text consumer search promise. Conversations are mailbox-scoped conversationId queries, not Gmail thread resources. Pagination is not a consistent snapshot. Only file attachments are downloaded, at most 2 MiB; item/reference attachments and external images are not fetched. Drafts use Graph JSON APIs; Microsoft owns MIME serialization and reply headers.
All recurring edits, deletions, attendee-affecting operations and RSVPs require human approval. In ordinary Graph v1.0 responses, private creates are gated too: the provider does not supply the negative-sharing evidence needed to prove an exemption safe. Updates always remain gated: Microsoft's event-update documentation does not establish atomic conditional-write enforcement. The connector rechecks versions immediately before dispatch but does not claim an external-edit lock or conditional-write guarantee. See calendar contracts.
Local installation
Requires Node.js 22 or later, a desktop browser, and an available OS credential store. Clone and build the source:
git clone https://github.com/torosent/copilot-outlook-connector.git
cd copilot-outlook-connector
npm ci --registry=https://registry.npmjs.org
npm test
npm pack
node dist/cli.js helpFor another local installation, install the resulting copilot-outlook-connector-0.1.0.tgz into a directory you control:
npm install --prefix /absolute/path/to/local-install /absolute/path/to/copilot-outlook-connector-0.1.0.tgz
node /absolute/path/to/local-install/node_modules/copilot-outlook-connector/dist/cli.js helpThe package is marked private to prevent accidental npm publication. Nothing installs or edits Copilot configuration automatically. No repository or package publication is required.
User-controlled account setup
Use a Microsoft public desktop client whose supported account types include personal Microsoft accounts and whose native redirect matches the connector's loopback policy. The recommended native redirect is http://localhost under Mobile and desktop applications. Do not add a secret to a desktop client or weaken an unrelated application's settings. If an existing registration is incompatible, create a separate suitable public client or make the specific registration change yourself.
Run node dist/cli.js help for the supported registration inspection/configuration and account commands. Registration inspection consumes only allowlisted application metadata; it is not token import or proof of current portal state. Configuration does not authenticate. Token-bearing exports and registrations declaring unsupported permissions are rejected. Use a separate least-privilege public client rather than weakening an existing application's configuration.
node dist/cli.js auth client inspect --file /absolute/path/to/application-manifest.json
node dist/cli.js auth client import --file /absolute/path/to/application-manifest.json
node dist/cli.js accounts add --client-id YOUR_PUBLIC_APPLICATION_ID
node dist/cli.js accounts listOnly deliberately invoking accounts add --client-id starts sign-in; the client selection is mandatory. accounts reauth ACCOUNT_ID may only reauthorize the same stable identity; accounts remove ACCOUNT_ID disables local access and cleans up local credential generations, not provider-wide consent. If either reports cleanupPending, unlock the credential store and run accounts cleanup ACCOUNT_ID. accounts cleanup without an ID retries all journaled inactive-generation cleanup.
Requested delegated permissions are User.Read, Mail.ReadWrite, Calendars.ReadWrite, openid, profile, and offline_access. Mail.ReadWrite grants broader mailbox mutation permission at OAuth level even though the connector exposes drafts only. Mail.Send is never requested. No application permissions, tenant impersonation, password flow or organizational fallback are used.
See authentication contract for exact commands, cache storage and issuer/account binding. No user-specific client ID, email or credential export belongs in reusable source, examples or test fixtures.
GitHub Copilot app integration
After local setup, print configuration from the actual installed path:
node /absolute/path/to/copilot-outlook-connector/dist/cli.js config printUse the emitted ordinary mcpServers entry with the GitHub Copilot app's Customize -> MCP flow or its supported MCP configuration editor. It contains an absolute Node executable, absolute CLI path, serve, and no credentials. Use a distinct server name, outlook-local; keep any Google server independent.
The output is inert. Printing configuration, help, doctor, STDIO discovery and empty-account listing do not start OAuth, enroll an authenticator, read existing vault entries or create account state. doctor reports local setup only, not successful Microsoft connectivity.
Human confirmation and recovery
Bootstrap the authenticator yourself in a trusted CLI, outside an agent workflow:
node dist/cli.js approvals enrollThe separate Outlook enrollment cannot be reset through MCP. A gated operation returns pending_approval and a localhost review URL. The human inspects the immutable account, target, resource versions, attendees, recurrence and notification effects, then completes the enrolled authenticator's user presence and user verification ceremony. No allow-all setting or SDK elicitation response substitutes for this. Never automate enrollment or approval.
Every write requires an explicit accountId and a stable, caller-chosen requestId. Repeating the same request returns its durable receipt; reusing the ID for different normalized arguments fails. Use operation_status to inspect and operation_cancel to cancel only before dispatch. An outcome_unknown operation must not be retried with a new ID. Inspect Outlook manually first. Microsoft transaction IDs are an additional event-create aid, not permission for automatic retries.
Storage and threat model
The independent namespace is copilot-outlook-connector: macOS Keychain, Windows Credential Manager, or desktop Linux Secret Service through shell-free secret-tool. Linux never silently falls back to kernel keyutils. Locked/unavailable vaults fail closed. Install libsecret's tools and unlock a desktop Secret Service on Linux.
MSAL caches are encrypted at rest with per-account/generation authenticated encryption; small encryption keys live in the OS vault, avoiding Windows credential-size limits. Metadata, operation receipts and authenticator public keys live in private local state. Mail bodies and access tokens are not put in receipts. No token is exported or passed as a process argument.
This protects the supported tool boundary and rejects forged approval responses. It cannot protect against arbitrary code already running as the same OS user, a replaced connector binary, compromised server, OS account or authenticator. See security and operational limitations.
Local acceptance
npm test
npm run smoke:packageThe package smoke builds a tarball, installs it with production dependencies only in an isolated temporary consumer, and exercises help/config/doctor/real STDIO discovery without credentials. It uses public-registry artifact URLs and integrity-cache installation, not a claim of fresh network downloads.
Offline fixtures do not establish native Windows/Linux behavior, physical-authenticator behavior, live app registration state or successful Outlook connectivity. Those require user-controlled platform acceptance. No live draft, invitation, RSVP or event mutation is part of automated acceptance.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/torosent/copilot-outlook-connector'
If you have feedback or need assistance with the MCP directory API, please join our Discord server