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.
curl -O https://raw.githubusercontent.com/ftaricano/mcp-outlook/main/CLAUDE.mdgit clone --depth 1 https://github.com/ftaricano/mcp-outlookWrote 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.
[](https://agentmods.dev/instructions/ftaricano/mcp-outlook/claude-md)<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.
<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>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.
| Model | Per session | Once 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 |
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.
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.
- Two fixed catalog families. The original server exposes exactly 40 tools and
scripts/smoke-test.jsenforces 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.jsonallowWritesfield, or via envPLUGIN_ALLOW_WRITES=true. The env is the authority:PLUGIN_ALLOW_WRITES=falseforces writes off regardless of what the file says; only when the env var is absent or empty does the file'sallowWritesfield decide (defaultfalse). Local handoffs are absent unlessPLUGIN_ALLOW_LOCAL_HANDOFFS=true; there is no config-file fallback.scripts/plugin-smoke-test.jsenforces 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 —strictObjectrejects the key outright — but it is an ordinary environment variable, so a.envin the process cwd sets it like any other (stdio.tsrunsdotenv.config()first). dotenv does not override an already-present value, so an explicitPLUGIN_ALLOW_SEND=falsein the environment still wins. It fails closed at startup unlessOUTLOOK_SEND_FROMnames a mailbox that is both in the plugin allowlist and covered by a non-emptyOUTLOOK_ALLOWED_SENDERS.send_emailtakes nomailboxargument: 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. - Every tool has a zod schema.
src/schemas/toolSchemas.tsis the gate —HandlerRegistry.handleToolrunsvalidateToolInputbefore dispatching. No handler method runs on unvalidated args. - Filesystem access goes through
pathGuard. Handlers never callfs.readFile/fs.writeFileon caller-supplied paths directly;src/services/fileManager.tsandsrc/services/emailService.tsalready route throughpathGuard.resolveSafe(). Any new file-touching code must go through the same door. - Graph calls go through
EmailService. No directClient.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.initWithMiddlewareinsrc/auth/graphAuth.ts), which includes the SDKRetryHandler. There is no in-house rate limiter. - 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. - Search negatives are evidence-bearing. Search code must follow
@odata.nextLinkwithin explicit limits and distinguishNOT_FOUNDfromSEARCH_INCOMPLETE,SEARCH_FAILED, andSEARCH_UNTRUSTED. Never turn a page-fetch failure or limit hit into a clean empty result. - Run telemetry is metadata-only.
scripts/lib/run-journal.jsmay 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. - Self-improvement emits proposals only.
outlook harvestis observational. It must not edit source, enqueue proposals, mutate skills, or bypass the external autonomy/session-harvest gates. - 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 toget_attachment_contentare caller-supplied at runtime and must never be committed, logged, or persisted by telemetry. - Mailbox identity is immutable per service. Never switch
TARGET_USER_EMAILor another process-global value around an operation. Plugin allowlists resolve opaque aliases to constructor-pinned mailbox services, and cache keys include mailbox identity. - 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.Readapp 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. - Graph permissions follow the exposed catalog. The default twelve-tool plugin requires only
application
Mail.Read. Enabling its five write tools requiresMail.ReadWrite. Enabling its send gate requiresMail.Send— the one case where the plugin needs it; leave that gate off and the plugin never does. The original 40-tool server requiresMail.ReadWriteand needsMail.Sendonly forsend_emailandreply_to_email. - Plugin downloads have aggregate budgets.
download_attachmentsapplies bothmaxBatchSizeandmaxDownloadBatchByteswhetherattachmentIdsis supplied or omitted. No attachment may start writing when its real decoded size exceeds the remaining byte budget. - Outbound sending goes through
senderPolicy. The original server has exactly two paths that put mail on the wire —EmailService.sendEmail()andEmailService.replyToEmail()— and both resolve their mailbox throughsrc/security/senderPolicy.tsbefore entering theirtryblock, because both catches rewrite errors and would disguise a refusal as a retryable failure. WhenOUTLOOK_ALLOWED_SENDERSis 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_FROMredirects 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_DOMAINSis the second half of the gate and aims at a different threat: pinning the sender stops impersonation, bounding recipients stops exfiltration. It checksto/cc/bcctogether, matches the exact domain after@(a subdomain does not inherit its parent), and makesreply_to_emailrefuse outright — a reply's recipients come from the original message, i.e. from the untrusted content the allowlist exists to contain.create_draftis deliberately outside both gates. Any new outbound call site must pass them —tests/security/outboundCallSites.test.tsfails if an outbound Graph route appears outsideEmailService, or if their number changes. The plugin'ssend_emailreaches the wire through that sameEmailService.sendEmail, so it inherits this gate rather than bypassing it. - Local handoffs are opaque, private, and fail closed. They use only the fixed
~/.jarvishub-mcp/outlook-handoffsroot, never a caller-supplied path. A0700bundle contains only0600payload.binplusmanifest.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.
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.
- 3d ago Changed · +4 lines · +49 tokens per session 5e54b8e4aa41
- 9d ago First seen · 142 lines · 2,805 tokens per session scan A 3dd542362f83
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.
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.
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.
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).
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).
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.
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.