Which AI agents on your machine can reach your email, calendar and messages?
whocanread reads the MCP config of every coding agent and AI desktop app it knows (Claude Code, Claude Desktop,
Cursor, Codex, Windsurf, VS Code, Gemini CLI, Zed, Cline), lists every MCP server they load, and sorts each one by
what it can touch: email, calendar, messages, files, shell, browser, payments. It also flags secrets written in plain
text inside those configs, by key name only, never the value.
One Python file, standard library only, nothing leaves your machine unless you pass --jev.
Built with Claude Opus 5.5. Inspired by Shikhar asking on X for a tool that tracks every AI and app with access to email, calendar and SMS.
python3 whocanread.py # scan this machine, keyword rules, fully offline
python3 whocanread.py --root ~/code # also project configs: .mcp.json, .cursor/mcp.json, .vscode/mcp.json
TYPESAFE_API_KEY=... python3 whocanread.py --jev # servers the rules cannot place go to Jev
python3 whocanread.py --jsonOutput looks like:
14 MCP servers across 3 agents
EMAIL 1: Claude Code > gmail
MESSAGES 2: Cursor > slack, Claude Desktop > whatsapp
FILES 3: ...
SHELL 1: Codex > term
PLAIN-TEXT SECRETS in 2 server configs (names only):
Claude Code > gmail: GMAIL_TOKEN (~/.claude.json)
3 servers can reach your email, calendar or messages.
To see how far keyword rules get and what a small decision model adds, every server in the official MCP registry was sorted three ways on 24 September 2026: 35,606 servers (latest version of each), judged from name, title and description.
| Can reach email, calendar or messages | |
|---|---|
| Jev, all 35,606 servers | 1,049 |
| Keyword rules, all 35,606 servers | 1,937 |
Jev: 35,606 decisions (seven yes/no questions each), $0.75 billed in total, 4 min 16 s wall clock on 24 threads, median 0.163 s per decision.
Reference: Claude Opus 5.5 labelled a random 300 of the same servers (seed 7, 50 per call through the Claude Code CLI, 0.445 s per server). Against it:
| Jev | Keyword rules | |
|---|---|---|
| Same answer on "touches email, calendar or messages" | 297 of 300 | 290 of 300 |
| Exactly the same seven labels | 273 of 300 | 247 of 300 |
Per category (counts over the full registry, F1 against Opus 5.5 on the sample):
| Category | Jev count | Rules count | Opus positives in sample | Jev F1 | Rules F1 |
|---|---|---|---|---|---|
| 377 | 803 | 2 | 1.0 | 0.667 | |
| calendar | 366 | 439 | 3 | 0.667 | 0.667 |
| messages | 484 | 845 | 2 | 1.0 | 0.0 |
| files | 1,471 | 1,606 | 14 | 0.455 | 0.385 |
| shell | 1,101 | 226 | 5 | 0.667 | 0.0 |
| browser | 615 | 598 | 3 | 0.667 | 0.667 |
| payments | 1,048 | 2,807 | 9 | 0.625 | 0.312 |
Caveat: the sample holds few positives per category, so per-category F1 moves a lot with one server.
The keyword rules over-flag (a "chat" or "payment" word in a description is not access), which is why the local
scan uses them only as a first pass and --jev for the rest. Opus 5.5 is the reference here, not ground truth.
Every decision is committed: data/jev.jsonl, data/rules.jsonl,
data/opus.jsonl, totals in data/results.json,
the registry snapshot in data/registry.json.
Reproduce:
python3 bench/fetch_registry.py
python3 bench/registry_bench.py rules
TYPESAFE_API_KEY=... python3 bench/registry_bench.py jev --threads 24
python3 bench/registry_bench.py opus --n 300
python3 bench/registry_bench.py score| Agent | Config |
|---|---|
| Claude Code | ~/.claude.json (global and per project), ~/.claude/settings.json, project .mcp.json |
| Claude Desktop | claude_desktop_config.json (macOS, Linux, Windows) |
| Cursor | ~/.cursor/mcp.json, project .cursor/mcp.json |
| Codex | ~/.codex/config.toml |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
| VS Code | user settings.json and mcp.json, project .vscode/mcp.json |
| Gemini CLI | ~/.gemini/settings.json |
| Zed | ~/.config/zed/settings.json |
| Cline | cline_mcp_settings.json |
Limits: it sees what the configs declare, not what a server does at run time, and it does not list OAuth grants you gave to apps in your Google or Microsoft account (those live in the provider's security page).
python3 test_whocanread.pyMIT license.

0 comments
log in to comment.