Metadata-Version: 2.4
Name: ews-mcp-orf
Version: 4.6.0
Summary: EWS MCP server — a lean, safety-gated, cache-first tool surface for an executive-mailbox assistant (see DESIGN.md). Internally packaged fork of azizmazrou/ews-mcp; provenance in PROVENANCE.md at the repo root.
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: exchangelib==5.0.3
Requires-Dist: jsonschema>=4.21
Requires-Dist: mcp<2,>=1.27
Requires-Dist: pydantic>=2.8
Requires-Dist: pydantic-settings>=2.5
Requires-Dist: truststore>=0.10
Requires-Dist: requests-negotiate-sspi>=0.5.2; platform_system == "Windows"
Requires-Dist: tzdata
Requires-Dist: uvicorn>=0.30
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"

# ews-mcp-orf

MCP server for an on-premises Microsoft Exchange mailbox via EWS — a lean,
safety-gated tool surface for LLM assistants: capability tiers, send
kill-switch, two-phase content-bound send confirmation, recipient guard,
and a hash-chained audit log.

> This is the internally packaged distribution of
> [`azizmazrou/ews-mcp`](https://github.com/azizmazrou/ews-mcp) (MIT).
> It carries local hardening patches (attachment size cap, recipient
> canonicalization, audit fail-closed, persistent confirm tokens,
> system-trust TLS). Full architecture and development docs live in the
> source repository.

## Install & run (stdio — the default)

Requires [uv](https://docs.astral.sh/uv/) (a single EXE; it manages its
own Python) — no Docker, no venv, no checkout:

```bash
uvx --from ews-mcp-orf ewsmcp
```

Pin a version for pilot deployments:

```bash
uvx --from ews-mcp-orf==4.5.0a1.post1 ewsmcp
```

**Claude Code** (one command, then restart the session):

```bash
claude mcp add exchange \
  -e EWS_SERVER_URL="https://mail.example.com/EWS/Exchange.asmx" \
  -e EWS_EMAIL="user@example.com" \
  -e EWS_USERNAME="DOMAIN\\user" \
  -e EWS_PASSWORD="…" \
  -e EWS_CAPABILITY_TIER="read" \
  -e SEND_ENABLED="false" \
  -e EWS_TZ="Europe/Vienna" \
  -- uvx --from ews-mcp-orf ewsmcp
```
On Windows, Integrated Authentication is available as an explicit opt-in:

```bash
EWS_AUTH_MODE=process \
EWS_SERVER_URL="https://mail.example.com/EWS/Exchange.asmx" \
EWS_EMAIL="user@example.com" \
uvx --from ews-mcp-orf ewsmcp
```

This uses the current Windows logon token through SSPI and does not use
`EWS_USERNAME` or `EWS_PASSWORD`. The default `EWS_AUTH_MODE=credentials`
remains portable across Windows, Linux and macOS.


**Claude Desktop** — add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "exchange": {
      "command": "uvx",
      "args": ["--from", "ews-mcp-orf", "ewsmcp"],
      "env": {
        "EWS_SERVER_URL": "https://mail.example.com/EWS/Exchange.asmx",
        "EWS_EMAIL": "user@example.com",
        "EWS_USERNAME": "DOMAIN\\user",
        "EWS_PASSWORD": "…"
      }
    }
  }
}
```

Any MCP client works the same way: command = `uvx --from ews-mcp-orf ewsmcp`,
credentials in `env`. The server speaks **stdio** — your client starts it
as a child process; nothing listens on the network, and it reaches
Exchange through whatever network your machine has (including corporate VPN).

## What you get

- **28 tools** across mail, calendar, tasks, contacts, and people lookup —
  short stable aliases (`m12`, `e3`) instead of 150-char raw EWS ids.
- **Token-lean responses**: cleaned bodies, alias-only ids, ~60-token cards.
- **Cache-first reads**: a background delta-sync mirrors folders into a
  local SQLite store; warm reads answer in milliseconds with provenance
  (`{"source": "cache", "as_of": …}`) and fall back to live EWS.
  Arabic search matches across orthographic variants.
- **TLS from the system trust store** (truststore): officially signed
  Exchange certificates work out of the box — no `SSL_CERT_FILE` needed.

## Safety architecture (defaults are safe)

| Control | Default | Effect |
|---|---|---|
| `EWS_CAPABILITY_TIER` | `draft` | `read` ⊂ `draft` ⊂ `full` — above-tier tools are never registered |
| `SEND_ENABLED` | `false` | Global send kill-switch; no send tools registered while `false` |
| Recipient guard | off | Glob allow/deny lists enforced on every send/invite recipient |
| Two-phase send | always on | Sends require a content-bound single-use confirm token; editing the draft in between invalidates it |
| Send rate cap | 10/hour | Hard ceiling on send-class operations |
| Audit chain | on | Hash-chained log in `DATA_DIR`; verify with `verify_audit_chain.py` |

For least privilege, run pilot users with:

```bash
EWS_CAPABILITY_TIER=read SEND_ENABLED=false
```

## Key configuration (env)

| Variable | Default | Meaning |
|---|---|---|
| `EWS_SERVER_URL` / `EWS_EMAIL` | — | Exchange endpoint and mailbox SMTP address |
| `EWS_AUTH_MODE` | `credentials` | `credentials` (portable) or `process` (Windows SSPI current logon; explicit opt-in) |
| `EWS_USERNAME` / `EWS_PASSWORD` | — | Required in `credentials` mode; omit in Windows `process` mode |
| `EWS_CAPABILITY_TIER` | `draft` | Tool-surface tier (`read`/`draft`/`full`) |
| `SEND_ENABLED` | `false` | Send kill-switch |
| `DATA_DIR` | `~/.ewsmcp` | Aliases, audit chain, cache. Cloud-synced paths (OneDrive/Dropbox/…) are **refused** |
| `EWS_CACHE_ENABLED` | `true` | Local mirror; `false` = pure live EWS, nothing on disk |
| `EWS_TZ` | `Asia/Riyadh` | Timezone for date grammar and display |
| `EWS_INSECURE_SKIP_VERIFY` | `false` | Keep `false` — TLS verification is mandatory |

The server never exits on boot: transports bind before any Exchange
contact, the connection manager retries with backoff, and health state
is observable via `get_server_status` (works over stdio and while cold).

## Provenance & license

This package is built from a pinned upstream commit with local security
patches (MIT). Version scheme: `<upstream>.post<n>`. See the packaging
repository's `PROVENANCE.md` for the exact commit and upgrade process.
Upstream project and full docs:
[github.com/azizmazrou/ews-mcp](https://github.com/azizmazrou/ews-mcp).
