mcp-outlook: Instructions file for Claude Code

CLAUDE.md

mcp-outlook CLAUDE.md is an instructions file for Claude Code from ftaricano/mcp-outlook. It costs 2,854 tokens per session, scanned A, original, MIT.

Instructions for an MCP server and command-line tool that connects coding agents to Microsoft Outlook email through Microsoft Graph, Microsoft's email service.

In plain words
What is it for?
Use them when maintaining the Outlook integration, checking its architecture and security rules, or adding a new email-related tool.
Why use it?
They document the system's fixed tool sets and safety rules, including limits on mailbox access, changes, attachments, and sending email.

Instructions file for Claude Code

Written for Claude Code: the file is CLAUDE.md. Also seen: mentions CLAUDE.md; mentions Claude Code.

This is ftaricano/mcp-outlook's own configuration. It tells Claude Code how to work on mcp-outlook itself, so it is not a mod to install elsewhere. Copy it as a starting point and replace the rules that are about this project. Everything mcp-outlook configures →

Reuse

Borrowing it

Nothing to install: this file belongs to ftaricano/mcp-outlook. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.

Copy the file
curl -O https://raw.githubusercontent.com/ftaricano/mcp-outlook/main/CLAUDE.md
Clone the repo
git clone --depth 1 https://github.com/ftaricano/mcp-outlook

Made for: Claude Code.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for mcp-outlook CLAUDE.md

README.md
[![agentmods](https://agentmods.dev/badge/instructions/ftaricano/mcp-outlook/claude-md/github.svg)](https://agentmods.dev/instructions/ftaricano/mcp-outlook/claude-md)
Your own site
<a href="https://agentmods.dev/instructions/ftaricano/mcp-outlook/claude-md"><img src="https://agentmods.dev/badge/instructions/ftaricano/mcp-outlook/claude-md/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for mcp-outlook CLAUDE.md

Your own site · 80×15
<a href="https://agentmods.dev/instructions/ftaricano/mcp-outlook/claude-md"><img src="https://agentmods.dev/badge/instructions/ftaricano/mcp-outlook/claude-md.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 2,854 This file is loaded in full into every session.
When invoked 2,854 The same file — it is already loaded in full.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.02854 $0.02854
Opus 5 $0.01427 $0.01427
Sonnet 5 $0.00571 $0.00571
Haiku 4.5 $0.00285 $0.00285

Measured 3d ago against content hash 5e54b8e4aa41, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-09, from the pricing page.

Security

Grade A, and why

mcp-outlook CLAUDE.md scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 3d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

CLAUDE.md · 146 lines

How it starts

The opening of the file, as written. The whole thing — 146 lines — stays where its author put it; the contents beside it link to each section on GitHub.

CLAUDE.md — agent notes

Guidance for agents working on this repo. End-user docs (tool catalog, setup, troubleshooting) live in README.md; don't duplicate them here.

What this is

MCP server exposing Microsoft Graph email operations as 40 tools over stdio, plus a standalone outlook CLI wrapper. A separate multi-mailbox plugin supports allowlisted search, reading, and bounded attachment access over stdio and loopback Streamable HTTP. It exposes twelve read-only tools by default, two local handoff tools only when that separate gate is enabled, five additional non-delete tools only when mailbox writes are explicitly enabled, and one send tool only when a third gate is enabled and a sending mailbox is pinned by configuration. Auth is Azure AD client-credentials (no user login). The original server remains single-mailbox per process; plugin services pin mailbox identity per instance.

Hard invariants

These are enforced by CI or by design. Don't regress them.

  1. Two fixed catalog families. The original server exposes exactly 40 tools and scripts/smoke-test.js enforces that count. The plugin exposes exactly twelve physically read-only tools by default, two independently gated local handoff tools, and five additional mailbox-write tools (move/copy/mark/download/create_draft) when writes are enabled — via the plugin.json allowWrites field, or via env PLUGIN_ALLOW_WRITES=true. The env is the authority: PLUGIN_ALLOW_WRITES=false forces writes off regardless of what the file says; only when the env var is absent or empty does the file's allowWrites field decide (default false). Local handoffs are absent unless PLUGIN_ALLOW_LOCAL_HANDOFFS=true; there is no config-file fallback. scripts/plugin-smoke-test.js enforces the full gate matrix: 12 / 14 / 17 / 19 without sending, and 13 / 15 / 18 / 20 with it. Every delete operation is impossible by construction — no dispatch branch exists for one in the plugin, at any gate combination. Sending is a third, independent gate (PLUGIN_ALLOW_SEND=true) exposing exactly one tool. No fallback to the plugin's JSON config — strictObject rejects the key outright — but it is an ordinary environment variable, so a .env in the process cwd sets it like any other (stdio.ts runs dotenv.config() first). dotenv does not override an already-present value, so an explicit PLUGIN_ALLOW_SEND=false in the environment still wins. It fails closed at startup unless OUTLOOK_SEND_FROM names a mailbox that is both in the plugin allowlist and covered by a non-empty OUTLOOK_ALLOWED_SENDERS. send_email takes no mailbox argument: the plugin reads untrusted mail from every allowed mailbox, so a caller-nameable sender would be an input a malicious message could try to steer. The sending mailbox is not sayable, only configurable.
  2. Every tool has a zod schema. src/schemas/toolSchemas.ts is the gate — HandlerRegistry.handleTool runs validateToolInput before dispatching. No handler method runs on unvalidated args.
  3. Filesystem access goes through pathGuard. Handlers never call fs.readFile / fs.writeFile on caller-supplied paths directly; src/services/fileManager.ts and src/services/emailService.ts already route through pathGuard.resolveSafe(). Any new file-touching code must go through the same door.
  4. Graph calls go through EmailService. No direct Client.api() in handlers — that bypasses response caching (CacheManager) and the batch helpers. Retry/throttling (429 + Retry-After) is not custom: it comes from the Graph SDK's default middleware chain (Client.initWithMiddleware in src/auth/graphAuth.ts), which includes the SDK RetryHandler. There is no in-house rate limiter.
  5. HTML template inputs are escaped by default. src/templates/ must keep escaping user-controlled fields before rendering. Do not add a trusted-HTML bypass without an explicit sanitizer and tests.
  6. Search negatives are evidence-bearing. Search code must follow @odata.nextLink within explicit limits and distinguish NOT_FOUND from SEARCH_INCOMPLETE, SEARCH_FAILED, and SEARCH_UNTRUSTED. Never turn a page-fetch failure or limit hit into a clean empty result.
  7. Run telemetry is metadata-only. scripts/lib/run-journal.js may store argument names/types, counters, durations, statuses, and normalized error classes. It must never persist argument values, message content/metadata, attachment names, credentials, or raw errors.
  8. Self-improvement emits proposals only. outlook harvest is observational. It must not edit source, enqueue proposals, mutate skills, or bypass the external autonomy/session-harvest gates.
  9. This is a public repo — no deployment-specific data. The code, tests, docs, and fixtures must stay free of any specific tenant's operational data: real mailbox addresses, client / company / person names, sender identities, folder maps, or attachment passwords. Anything deployment-specific is caller-supplied at runtime — env vars, or an external config / search-memory file passed by path — never committed here. Tests and examples use fictional data only. Rationale: committed content is world-readable and effectively permanent; a leak of an operator's business data cannot be undone. Capabilities that consume such data (e.g. multi-mailbox search, document confirmation, an index-backed cache) belong here as generic mechanisms; the data they read stays in the caller's private config. The optional search-memory file (PLUGIN_SEARCH_MEMORY_PATH) and ZIP passwords passed to get_attachment_content are caller-supplied at runtime and must never be committed, logged, or persisted by telemetry.
  10. Mailbox identity is immutable per service. Never switch TARGET_USER_EMAIL or another process-global value around an operation. Plugin allowlists resolve opaque aliases to constructor-pinned mailbox services, and cache keys include mailbox identity.
  11. HTTP is loopback-only in this repo. Remote ChatGPT use requires a separately reviewed HTTPS OAuth 2.1 resource-server layer and a separate Graph Mail.Read app registration. The HTTP entrypoint also forces the twelve-tool physically read-only catalog; local handoffs, mailbox writes, and sending are unavailable regardless of plugin configuration or environment gates. The stdio entrypoint retains its independent gates.
  12. Graph permissions follow the exposed catalog. The default twelve-tool plugin requires only application Mail.Read. Enabling its five write tools requires Mail.ReadWrite. Enabling its send gate requires Mail.Send — the one case where the plugin needs it; leave that gate off and the plugin never does. The original 40-tool server requires Mail.ReadWrite and needs Mail.Send only for send_email and reply_to_email.
  13. Plugin downloads have aggregate budgets. download_attachments applies both maxBatchSize and maxDownloadBatchBytes whether attachmentIds is supplied or omitted. No attachment may start writing when its real decoded size exceeds the remaining byte budget.
  14. Outbound sending goes through senderPolicy. The original server has exactly two paths that put mail on the wire — EmailService.sendEmail() and EmailService.replyToEmail() — and both resolve their mailbox through src/security/senderPolicy.ts before entering their try block, because both catches rewrite errors and would disguise a refusal as a retryable failure. When OUTLOOK_ALLOWED_SENDERS is set, any mailbox outside it is refused before Graph is called; unset means unrestricted, since the deployment's addresses cannot live in this repo (invariant 9). OUTLOOK_SEND_FROM redirects new messages only — a reply belongs to the mailbox that owns the original message, and redirecting it would point at a foreign message id. OUTLOOK_ALLOWED_RECIPIENT_DOMAINS is the second half of the gate and aims at a different threat: pinning the sender stops impersonation, bounding recipients stops exfiltration. It checks to/cc/bcc together, matches the exact domain after @ (a subdomain does not inherit its parent), and makes reply_to_email refuse outright — a reply's recipients come from the original message, i.e. from the untrusted content the allowlist exists to contain. create_draft is deliberately outside both gates. Any new outbound call site must pass them — tests/security/outboundCallSites.test.ts fails if an outbound Graph route appears outside EmailService, or if their number changes. The plugin's send_email reaches the wire through that same EmailService.sendEmail, so it inherits this gate rather than bypassing it.
  15. Local handoffs are opaque, private, and fail closed. They use only the fixed ~/.jarvishub-mcp/outlook-handoffs root, never a caller-supplied path. A 0700 bundle contains only 0600 payload.bin plus manifest.json; the manifest is the final commit marker. Replay revalidates request fingerprint, exact manifest shape, modes, size, and SHA-256. The MCP never returns bytes, Base64, internal paths, or the request fingerprint. Quotas bound one payload, aggregate payload bytes, and committed bundle count.

Read the full file on GitHub · 146 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 3d ago Changed · +4 lines · +49 tokens per session 5e54b8e4aa41
  2. 9d ago First seen · 142 lines · 2,805 tokens per session scan A 3dd542362f83

Subscribe to this mod's changes

mcp-outlook CLAUDE.md is an instructions file published in the GitHub repository ftaricano/mcp-outlook (2 stars, last pushed 2d ago), licensed MIT. It adds 2,854 tokens to every session, about $0.0143 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.

Related

Other instructions, from other repositories

next.js AGENTS.md

AGENTS.md instructions for vercel/next.js, covering next.js development guide, codebase structure, monorepo overview, core package: packages/next and other important packages.

vercel/next.js · 7,296 tokens

codex AGENTS.md

AGENTS.md instructions for openai/codex, covering rust/codex-rs, the codex-core crate, code review rules, crate api surface and model visible context.

openai/codex · 5,153 tokens

vscode buildNext.instructions.md

Working notes and architecture documentation for the new esbuild-based build system in build/next. Use when making changes to the new build pipeline (transpile/bundle commands, NLS plugin, source-map handling, resource copying, or self-hosting watch tasks).

microsoft/vscode · 6,785 tokens

vscode oss-third-party-notices.instructions.md

Instructions for microsoft/vscode, covering vs code oss third-party-notices pipeline, architecture, pipeline flow in ci, applying the notice (cutover) and fallback chain (never fail the build).

microsoft/vscode · 5,001 tokens

langchain AGENTS.md

AGENTS.md instructions for langchain-ai/langchain, covering global development guidelines for the langchain monorepo, corridor security analysis, project architecture and context, monorepo structure and development tools & commands.

langchain-ai/langchain · 4,469 tokens

deepseek-harness AGENTS.md

AGENTS.md instructions for deepseek-ai/deepseek-harness, covering agents.md, pre-stable apis and released session data, repository layout, commands and host sandbox failures.

deepseek-ai/deepseek-harness · 3,737 tokens