# Mail Index

> A local, agent-queryable mail intelligence layer — progressive mailbox index + MCP server that gives AI agents recall over your email without handing them the keys.

- **Type:** MCP server
- **Install:** `agentstack add mcp-alunsoldantarctica-mail-index`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [unsoldgroup](https://agentstack.voostack.com/s/unsoldgroup)
- **Installs:** 0
- **Category:** [Databases](https://agentstack.voostack.com/c/databases)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [unsoldgroup](https://github.com/unsoldgroup)
- **Source:** https://github.com/unsoldgroup/mail-index
- **Website:** https://unsoldgroup.github.io/mail-index/

## Install

```sh
agentstack add mcp-alunsoldantarctica-mail-index
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# mail-index

[](https://www.npmjs.com/package/mail-index)
[](https://www.npmjs.com/package/mail-index)
[](https://github.com/alunsoldantarctica/mail-index/stargazers)
[](https://github.com/alunsoldantarctica/mail-index/network/members)
[](https://github.com/alunsoldantarctica/mail-index/actions/workflows/ci.yml)
[](LICENSE)

mail-index downloads a **preview of your whole inbox** to your machine, then
smartly fetches the full text of the messages that matter as you use it. That
local index lets your AI agent run **true summarization and recall over your
entire mailbox** — instead of being trapped behind Gmail's search bar.

It works through a **local MCP server**, so any agent (Claude, Codex, any MCP
client) can query it. Local-first — the index never leaves your machine.
Read-only by default — it never sends or mutates your mail unless you
explicitly opt into archive + label edits (a least-privilege `gmail.modify`
re-auth; never send or delete). See [ADR-0007](docs/adr/0007-opt-in-mailbox-writes.md).

  
    
  
  
  Ask a vague question → one local MCP call → ranked, snippet-first answer.
  Interactive version →

> **Status: v1.0 — published.** Progressive sync, the correspondence graph, the
> interest engine, curation, the full 23-tool MCP surface, and the write-back
> loops are built and tested — and `mail-index` is live on
> **[npm](https://www.npmjs.com/package/mail-index)** with a
> **[`.mcpb` bundle](https://github.com/alunsoldantarctica/mail-index/releases/latest)**.
> Still in progress: the bundled Option A OAuth client and signed one-click
> installers. Architecture lives in
> **[docs/PLAN.md](docs/PLAN.md)**; start with **[docs/INSTALL.md](docs/INSTALL.md)**.

> [!TIP]
> **New in v1.4 — opt-in mailbox writes + human-readable labels.**
> mail-index can now **archive** a message and **edit its labels** directly on
> Gmail — via the `archive` / `label` CLI commands and the `archive_message` /
> `modify_labels` MCP tools, on both the gog and gws adapters. It stays
> **read-only by default**: writes are unreachable until you opt in with a
> *least-privilege* `gmail.modify` grant (**never** send or delete) — enable per
> account with `mail-index setup --account  --enable-writes` or the
> bundled `scripts/enable-writes.sh`. Labels now render as their **human names**
> everywhere (the index caches Gmail's label catalogue and resolves
> `Label_3546…` → *"Expedition Insure"* in both directions), and you can pass a
> friendly label name to `label --add/--remove`. The local-only / zero-egress
> guarantee is unchanged. See **[ADR-0007](docs/adr/0007-opt-in-mailbox-writes.md)**.

---

## How it works

1. **Progressive sync** — metadata for the whole mailbox in minutes; bodies
   fetched selectively.
2. **Graph** — contacts, domains, threads; centrality + communities over your
   *human* (non-bulk) mail.
3. **Interest** — an engagement score per contact from read/reply/star/importance
   signals. A *seed for your curation*, not an autonomous decision.
4. **Curate** — you (via your agent, or a CLI wizard) confirm who/what matters;
   that profile drives which bodies get fetched.
5. **Query** — your agent searches, traverses the graph, and reads the messages
   that matter, all locally via MCP.

  
    
  
  
  Important messages prewarm a local index; the MCP reads from it, touching
  Gmail again only when a needed body isn't there yet.
  Interactive version →

## Quick start

Requires **Node 24+** and a Gmail `MailSource` adapter — **`gog`** (recommended)
or **`gws`**. Reading Gmail needs a Google OAuth client, and you get one **two
ways**: use the **mail-index beta client** (skip Google Cloud entirely;
[request access](https://github.com/alunsoldantarctica/mail-index/issues/new?template=beta_access.yml)
to join the ~100-user test list) or **bring your own** Google Cloud client (no
cap, no request — we walk you through it). See
[docs/INSTALL.md §2](docs/INSTALL.md#2-connect-a-mailbox-pick-an-oauth-path)
and [docs/oauth-and-verification.md](docs/oauth-and-verification.md).

```sh
npm install -g mail-index                    # or: pnpm add -g mail-index

mail-index init                              # scaffold the config
# …connect a mailbox (own OAuth client, read-only) — see docs/INSTALL.md §2 / agent-install.md…
mail-index sync  --account personal --since 6mo
mail-index graph build --account personal
mail-index search "that contract we discussed"
```
*(Prefer source? `git clone …`, `pnpm install && pnpm build`, then run the bins
as `node dist/cli/index.js …`.)*

### Add to Claude

The MCP server registers in one step, but it still needs a mailbox connected
first (see the walkthrough). A `.mcpb`/`claude mcp add` only **adds the server** —
it doesn't install the adapter, sign you in, or sync.

- **Claude Code:** `claude mcp add --transport stdio mail-index -- npx -y -p mail-index mail-index-mcp`
  (on **Windows**, prefix with `cmd /c`: `… -- cmd /c npx -y -p mail-index mail-index-mcp` —
  bare `npx`/`.cmd` won't spawn. See [docs/INSTALL.md §7](docs/INSTALL.md).)
- **Any MCP client (manual):**
  ```jsonc
  { "mcpServers": { "mail-index": { "command": "mail-index-mcp" } } }
  ```
- **Claude Desktop:** download the **[`.mcpb` bundle](https://github.com/alunsoldantarctica/mail-index/releases/latest/download/mail-index.mcpb)**
  and double-click it (unsigned during beta — you may need to allow it in System
  Settings / Windows SmartScreen). The bundle is **self-contained** (ships its own
  dependencies, run by Claude Desktop's bundled Node — no npx, network, or system
  Node needed) so it installs identically on Windows/macOS/Linux. A signed
  all-in-one installer that *also* installs the adapter, signs you in, and syncs is
  still in progress; there is no `claude://` install link.

**Teach your agent the common moves.** The MCP server already tells the agent
*when* to reach for it (purchases, receipts, bookings, "who said what", "catch me
up"), and the repo ships a Claude **[Agent Skill](skills/mail-index/SKILL.md)**
with the typical recipes (find purchases, catch up, find a contact's mail,
summarize a sender). Drop it in for Claude Code/Desktop:

```sh
mkdir -p ~/.claude/skills && cp -R skills/mail-index ~/.claude/skills/
```

Full walkthrough (auth, curation, enrichment, scheduled sync, desktop-app
gotchas) → **[docs/INSTALL.md](docs/INSTALL.md)**. Driving setup with an agent →
**[docs/agent-install.md](docs/agent-install.md)**.

## What to expect — time & storage

The index keeps metadata for every message and full text only where it earns it,
so it grows with message *count*, not mailbox size — about **1.5% of your Gmail**.
First sync runs ~50 messages/min (one-time, incremental after); search is instant.
Start with `--since 1mo` for value in minutes, then expand. Sizing table & growth
path → **[docs/INSTALL.md §9](docs/INSTALL.md#9-grow-your-index-intelligently)**.

## Why it's lighter than Gmail search

Stock Gmail-API MCPs are query-based **lookup** tools — exact query, a network
round-trip per call, raw payloads dumped into the model's context. mail-index
answers *vague* questions from a local **recall** index. Across a 100-question
suite on a real mailbox it answered every question for **15× fewer tokens** — and
the gap widens exactly where a query-based MCP has no primitive at all:
summarizing, relationships, and commitments.

  
    
  

Per-category tables, the read-one-message comparison, the tool-by-tool landscape,
and how to reproduce it all → **[docs/COMPARISON.md](docs/COMPARISON.md)**.

## Stack

TypeScript · `node:sqlite` (no native deps) · SQLite FTS5 · Graphology ·
`@modelcontextprotocol/sdk`. Node 24+. Pluggable `MailSource` adapters; ships two
Gmail transports — [`gog`](https://github.com/openclaw/gogcli) (recommended) and
Google's [`gws`](https://github.com/googleworkspace/cli).

## CLI

Two bins ship: `mail-index` (CLI) and `mail-index-mcp` (the stdio MCP server).

```
mail-index init                          Scaffold the operator config + data dir
mail-index sync    --account  [--since 30d|1mo] [--all] [--query ] [--limit N]
mail-index sync    --all-accounts        Sync every account by its policy presets
mail-index enrich  --account  [--profile | --rule direct|all] [--sender ] [--match ] [--limit N]
mail-index graph   build [--account  | --all-accounts]
mail-index curate  [--account ]       Interactive curation wizard (no-agent fallback)
mail-index compact [--account ] [--now]   Demote summarized bulk bodies (ADR-0003)
mail-index search   [--account ] [--limit N] [--enrich]
mail-index show      Print a message (auto-enriches a meta row)
mail-index open      Print the provider web URL (no fetch)
mail-index archive   Archive (drop INBOX) — opt-in write; needs gmail.modify
mail-index label    [--add ]... [--remove ]...  Opt-in write; needs gmail.modify
mail-index status  [--json]              Per-account freshness + counts
```

Writes are off by default. Enable archive + label edits for an account with
`mail-index setup --account  --enable-writes` (or the bundled
`scripts/enable-writes.sh `) — a least-privilege `gmail.modify` grant
(never send or delete). See [ADR-0007](docs/adr/0007-opt-in-mailbox-writes.md).

## Documentation

- **[docs/INSTALL.md](docs/INSTALL.md)** — generic onboarding (install,
  authenticate a MailSource, init, sync, curate, enrich, add the MCP server,
  scheduled-sync snippet).
- **[docs/MCP.md](docs/MCP.md)** — the 18-tool MCP reference for agent
  integrators: args, compact result shapes, the `index_as_of` freshness +
  command-handback contracts.
- **[docs/ADAPTERS.md](docs/ADAPTERS.md)** — the `MailSource` contract and how to
  write + contract-test a new adapter.
- **[docs/PLAN.md](docs/PLAN.md)** — architecture, data model, and the key
  decisions (ADR digest).
- **[SECURITY.md](.github/SECURITY.md)** + **[docs/THREAT-MODEL.md](docs/THREAT-MODEL.md)**
  — privacy posture, trust boundaries, prompt-injection stance, and a
  "verify our claims yourself" runbook. The local-only promise is enforced in CI
  by an [egress guard test](test/egress-guard.test.ts) — the core (`src/`) makes
  no network calls; the one exception is the opt-out launch-shim self-updater
  (`bin/selfupdate.mjs`, throttled npm-version check, `MAIL_INDEX_NO_AUTOUPDATE=1`
  to disable), audited by the same guard.

## About

Built by **[Unsold Group](https://unsold.group/al)** — a travel & insurtech
company building the groundwork to operate as an AI-native business: local-first,
agent-native infrastructure that gives AI real, queryable context to work from.
mail-index is one piece of that — giving agents durable memory of a mailbox
without handing them the keys to it.

More: **[unsold.group/al](https://unsold.group/al)**

## Project growth

[](https://star-history.com/#alunsoldantarctica/mail-index&Date)

## Feedback & contact

There's **no telemetry** — we only know what you tell us, so feedback is
genuinely welcome:

- 💬 **[Discussions](https://github.com/alunsoldantarctica/mail-index/discussions)** — questions, ideas, how you use it
- 🐞 **[Report a bug](https://github.com/alunsoldantarctica/mail-index/issues/new?template=bug_report.yml)** · 💡 **[Request a feature](https://github.com/alunsoldantarctica/mail-index/issues/new?template=feature_request.yml)**
- 🔒 Security/privacy issues → **[SECURITY.md](.github/SECURITY.md)** (private)
- 🌐 **[unsold.group/al](https://unsold.group/al)**

Inside your agent you can also just say *"report a mail-index bug"* — the MCP
server points the agent to a GitHub link for you to submit (it never sends
anything itself). See **[SUPPORT.md](.github/SUPPORT.md)**.

## License

[MIT](LICENSE)

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [unsoldgroup](https://github.com/unsoldgroup)
- **Source:** [unsoldgroup/mail-index](https://github.com/unsoldgroup/mail-index)
- **License:** MIT
- **Homepage:** https://unsoldgroup.github.io/mail-index/

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-alunsoldantarctica-mail-index
- Seller: https://agentstack.voostack.com/s/unsoldgroup
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
