Skip to main content
Glama
ZachPackull

outlook-evidence-mcp

by ZachPackull

outlook-evidence-mcp

A read-only Model Context Protocol server that lets an MCP client (Claude Code, Claude Desktop, etc.) search a Microsoft 365 / Outlook mailbox and export messages + attachments to a local folder, recording a chain-of-custody manifest (SHA-256 per file) so the collection is defensible as evidence.

Built for the case where you need to pull a specific set of email threads and their attachments out of Outlook — for litigation, compliance, or analysis — without granting broad, writeable, or tenant-wide access.

Design principles

  • Read-only. Requests only the delegated User.Read + Mail.Read Graph scopes. There are no send / delete / modify tools — none exist in the code.

  • Your mailbox only. Delegated auth (device-code flow) acts as the signed-in user. No application (app-only) permissions, so it can never read other people's mailboxes.

  • No secrets in the repo. You supply your own Entra app IDs via env. Device-code flow means there's no client secret at all. The OAuth token cache and the exported evidence are git-ignored.

  • Auditable collection. Every export appends a manifest.jsonl record: message id, internet message id, sender, subject, received time, and the SHA-256 + size of each saved file, plus the retrieval timestamp.

Related MCP server: Microsoft Graph MCP Server

Tools

Tool

What it does

outlook_authenticate

One-time device-code sign-in; returns a URL + code to complete in a browser

outlook_auth_status

Report whether the server is signed in

outlook_search

Search mail by free-text KQL (query) or structured from/since/until/folder

outlook_get_message

Fetch one message's metadata + body

outlook_list_attachments

List a message's attachments

outlook_save_message

Export one message as .eml + download its attachments + manifest entry

outlook_save_thread

Save every message in a conversation (+ attachments)

Messages are exported as .eml (full MIME via Graph /$value) to preserve headers and fidelity.

Prerequisites

  • Node.js 18+

  • A Microsoft 365 business tenant (personal @outlook.com accounts are not supported by Graph delegated mail here)

  • Rights to register an app and grant admin consent in your tenant (or an admin who will)

Setup

1. Register an Entra application (~5 min, one-time)

In portal.azure.comMicrosoft Entra ID → App registrations → New registration:

  1. Name: e.g. outlook-evidence-mcp. Supported account types: Accounts in this organizational directory only (single tenant).

  2. API permissions → Add a permission → Microsoft Graph → Delegated permissions → add User.Read and Mail.ReadGrant admin consent.

  3. Authentication → Advanced settings → Allow public client flows → Yes (enables device-code auth — no client secret, no redirect URI needed).

  4. Copy the Application (client) ID and Directory (tenant) ID from the app's Overview.

Conditional Access note: some tenants block the device-code flow via a CA policy. If sign-in is blocked, scope a CA exception for this app registration (an auth-code + localhost redirect variant isn't bundled yet — open an issue if you need it).

2. Install & build

npm install
npm run build      # compiles to dist/

3. Configure

Copy .env.example to .env and fill in your IDs (or pass the same vars via your MCP client config):

AZURE_CLIENT_ID=<application-client-id>
AZURE_TENANT_ID=<directory-tenant-id>
OUTPUT_DIR=./evidence
TOKEN_CACHE_PATH=./.token-cache.json

4. Register with your MCP client

Claude Code:

claude mcp add outlook-evidence \
  -e AZURE_CLIENT_ID=<client-id> \
  -e AZURE_TENANT_ID=<tenant-id> \
  -e OUTPUT_DIR=/absolute/path/to/evidence \
  -- node /absolute/path/to/outlook-evidence-mcp/dist/index.js

Or add it to your client's MCP config JSON:

{
  "mcpServers": {
    "outlook-evidence": {
      "command": "node",
      "args": ["/absolute/path/to/outlook-evidence-mcp/dist/index.js"],
      "env": {
        "AZURE_CLIENT_ID": "<client-id>",
        "AZURE_TENANT_ID": "<tenant-id>",
        "OUTPUT_DIR": "/absolute/path/to/evidence"
      }
    }
  }
}

5. Authenticate (one-time, interactive)

In an interactive session, call the outlook_authenticate tool. It returns something like:

To sign in, use a web browser to open https://microsoft.com/devicelogin and enter the code ABCD-EFGH.

Complete that in your browser. The refreshable token is cached locally; subsequent (including headless) runs won't prompt again until it expires.

Usage

Once authenticated, ask your MCP client to, e.g.:

  • "Search Outlook for mail from planet.com about the ISO 8583 spec."outlook_search

  • "Save that whole thread and its attachments to the evidence folder."outlook_save_thread

Everything lands in OUTPUT_DIR as .eml files + attachments, with an appended manifest.jsonl.

Security & privacy

  • Read-only, delegated, single-user. The Entra app registration is the hard boundary — even if you don't trust this code, you consent only to Mail.Read on your own mailbox.

  • The token cache (TOKEN_CACHE_PATH) holds live tokens — it is git-ignored and written 0600. Treat it like a credential.

  • The evidence folder is git-ignored. Do not commit collected mail.

  • The only network egress is https://graph.microsoft.com. No telemetry.

Development

npm run dev        # run from source (tsx)
npm run typecheck  # tsc --noEmit
npm test           # vitest (offline; Graph is mocked — no live calls)

License

MIT — see LICENSE.

Available Tools

7 tools
outlook_authenticateAuthenticate to OutlookA

Begin the one-time device-code sign-in. Returns a URL + code to complete in a browser. Read-only (Mail.Read).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It discloses the device-code flow, return of URL+code, and read-only scope. However, it does not detail error handling, state changes, or whether multiple calls are safe.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that efficiently conveys purpose, method, and scope. No extraneous words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with no output schema, the description is fairly complete. It specifies the return of a URL+code and the read-only scope. However, it lacks details on error conditions or timeout behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has no parameters, so the description does not need to add parameter information. The schema coverage is 100% (no params), and the description appropriately omits param details.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool initiates a one-time device-code sign-in, returns a URL and code, and specifies the read-only scope. It is specific and distinct from sibling tools like outlook_auth_status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Begin the one-time device-code sign-in,' indicating when to use it. However, it does not explicitly mention when not to use it or provide alternatives beyond implied differentiation from siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

outlook_auth_statusAuth statusA

Report whether the server is signed in.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. It correctly indicates a read-only status check, but doesn't mention any potential side effects, security requirements, or output format. Adequate for a simple tool but lacks depth.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single concise sentence that fully captures the tool's purpose with no extraneous information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has no parameters and no output schema, the description adequately states its function. However, it doesn't indicate if the result is a boolean or string, or possible error states. Slightly incomplete but sufficient for a simple status check.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters exist, so schema description coverage is 100%. Description adds no new parameter info, but baseline for 0-param tools is 4. No ambiguity.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool reports whether the server is signed in, using specific verb 'report' and resource 'server signed in status'. This distinguishes it from sibling tool outlook_authenticate which performs authentication.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance on when to use this tool versus alternatives like outlook_authenticate. The description only states the function without context on prerequisites or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

outlook_get_messageGet messageB

Fetch one message's full metadata + body (read-only).

ParametersJSON Schema
NameRequiredDescriptionDefault
messageIdYes

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It only states 'read-only', which indicates no side effects, but fails to disclose other behavioral traits such as authentication requirements, rate limits, or whether the operation is idempotent. For a fetch tool, more context is needed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence with no wasted words. It efficiently conveys the core action and key property (read-only).

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema and no annotations, the description lacks details about return format, error handling, authentication prerequisites, and what 'full metadata' includes. For a simple tool, it is minimally adequate but leaves significant gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, meaning the parameter 'messageId' has no description in the schema. The description adds minimal context by stating it fetches a message, implying messageId identifies which message, but does not specify format, source, or how to obtain it. This leaves ambiguity.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('fetch'), the resource ('one message'), and the scope ('full metadata + body'), and explicitly marks it as read-only. It distinguishes itself from sibling tools like outlook_save_message (write) and outlook_search (search).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for fetching a single message but does not provide explicit guidance on when to use this tool versus alternatives like outlook_search or outlook_list_attachments. No when-not-to-use or exclusions are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

outlook_list_attachmentsList attachmentsA

List a message's attachments (name, type, size).

ParametersJSON Schema
NameRequiredDescriptionDefault
messageIdYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so the description carries the full burden. It discloses the action is read-only (listing) and what fields are returned. No mention of authorization or error handling, but for a simple list tool this is acceptable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence with no unnecessary words. It is front-loaded with the action and resource. However, it could be slightly expanded for clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description lists returned fields (name, type, size) but does not mention whether attachments have IDs or if pagination exists. For a simple list with 1 param, it is minimally adequate but could be more complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter (messageId) with 0% schema description coverage. The tool description does not explain what messageId is or how to obtain it, leaving the agent to infer from context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the verb 'list' and the resource 'attachments of a message', and specifies the returned fields (name, type, size). It clearly distinguishes from sibling tools like outlook_get_message which retrieves the message itself.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when needing attachment details for a message, but lacks explicit guidance on when to use vs alternatives (e.g., outlook_get_message might include attachments). No when-not-to-use or comparison provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

outlook_save_messageSave message + attachmentsB

Export one message as .eml and download its attachments into the evidence folder, recording a chain-of-custody manifest entry (SHA-256 per file). Returns the saved file paths.

ParametersJSON Schema
NameRequiredDescriptionDefault
messageIdYes
includeAttachmentsNo

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, placing full burden on the description. It discloses key behaviors (export as .eml, download attachments, manifest entry, return paths) but omits important details such as authentication requirements, error handling (e.g., message not found), whether the evidence folder is created automatically, and any rate limits. Significant gaps remain for a tool that persists files.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence front-loaded with the primary action. It is concise and to the point, but could be slightly restructured for clarity (e.g., splitting into two sentences). Overall, it is efficient with no wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has modest complexity with two simple parameters and no output schema. The description covers main functionality and return value, but lacks details on prerequisites (authentication), error scenarios, and manifest specifics. Without annotations or output schema, more context would improve completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must add meaning. It mentions downloading attachments, implying the includeAttachments boolean, but does not explicitly state that the parameter controls this behavior. The format or constraints for messageId are also not clarified. Partial information is provided but does not fully compensate for the missing schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it exports a single message as .eml, downloads attachments, records chain-of-custody manifest with SHA-256, and returns file paths. This specific verb+resource+additional actions distinguishes it from sibling tools like outlook_save_thread and outlook_get_message.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies forensic usage with chain-of-custody, but does not explicitly state when to use this tool versus alternatives like outlook_save_thread or outlook_get_message. No exclusions or prerequisites are mentioned, though context from sibling names helps infer differences.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

outlook_save_threadSave whole threadB

Given any message id, save every message in its conversation (+ attachments) as .eml with manifest entries.

ParametersJSON Schema
NameRequiredDescriptionDefault
messageIdYes
includeAttachmentsNo

TDQS

B3.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry the behavioral burden. It discloses that the tool saves messages and attachments but does not mention important behavioral traits such as read-only nature, required authentication, rate limits, or error handling. The lack of output schema further limits transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that conveys the core functionality without extraneous information. It is front-loaded with the input requirement and efficiently communicates the action and outcome.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (2 parameters, no output schema, no annotations), the description is adequate but lacks details about output format, error handling, and permission requirements. For a comprehensive agentic use, more contextual completeness would be beneficial.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description only mentions 'message id' and 'attachments' indirectly, but the input schema has two parameters with no descriptions. With 0% schema coverage, the description adds minimal extra meaning beyond the parameter names. It does not explain the default value of includeAttachments or constraints on messageId.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: saving every message in a conversation along with attachments as .eml files with manifest entries. The verb 'save' and resource 'whole thread/conversation' are specific, and it distinguishes itself from the sibling tool 'outlook_save_message' which saves a single message.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when users need to save an entire email thread rather than a single message, but it does not explicitly state when to use this tool versus alternatives like outlook_save_message. No usage exclusions or context signals are provided, but the instructions are clear enough for basic selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 7 tool updatesv0.1.0
    • First observedoutlook_auth_status
    • First observedoutlook_authenticate
    • First observedoutlook_get_message
    • First observedoutlook_list_attachments
    • First observedoutlook_save_message
    • First observedoutlook_save_thread
    • First observedoutlook_search

TDQS

A3.9/5.0
Disambiguation5/5

Each tool has a clear and distinct purpose: authentication, status checking, fetching a message, listing attachments, saving a message, saving a thread, and searching. No overlapping functionality.

Naming Consistency4/5

Most tools follow a consistent 'outlook_verb_noun' pattern (e.g., get_message, save_message, search). However, outlook_auth_status is a noun-noun combination and outlook_authenticate is just a verb, causing minor inconsistency.

Tool Count5/5

With 7 tools, the set is well-scoped for the purpose of reading and saving Outlook emails as evidence. It covers authentication, retrieval, attachment handling, and search without being excessive.

Completeness5/5

The tool set covers the full evidence-gathering workflow: authenticate, search, retrieve messages, list/save attachments, and save entire threads. No obvious gaps for the stated read-only, chain-of-custody purpose.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables semantic search and AI-powered analysis of Outlook emails using RAG-based natural language queries and Vision AI for architectural documents, with specialized support for AEC workflows.
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides programmatic access to Microsoft Outlook mailboxes, enabling AI assistants to search, analyze, and extract insights from emails in personal and shared mailboxes.
    -

Latest Blog Posts

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/ZachPackull/outlook-evidence-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server