MCP hey agent
MCP server for Hey.com: read, send, search, and organise email from Claude or any MCP client.
Files of MCP hey
Sealjay/
Show the full text270 lines
mcp-hey
A local Model Context Protocol (MCP) server that gives Claude read/write access to your Hey.com inbox via reverse-engineered web APIs.
mcp-hey has two moving parts: a Bun/TypeScript MCP server that exposes Hey tools over stdio, and a small Python helper that uses the system webview to capture session cookies at login. Everything runs locally — no cloud relay, no credentials stored, just session cookies on disk.
Warning — unofficial API. Hey.com does not publish a public API; mcp-hey reverse-engineers its web endpoints and pairs them with browser-identical HTTP requests. Things can break without notice. The current documented surface lives in
docs/API.md.
Features
- Read emails from Imbox, Feed, Paper Trail, Set Aside, Reply Later, Drafts, Trash, and Spam
- Download attachments and parse calendar invites from emails
- Send and reply to email threads
- Search emails across boxes
- Organise mail (set aside, reply later, screen in/out, bubble up)
- Local SQLite cache for faster repeated reads and full-text search
- Lightweight — around 30 MB idle memory
- Browser-identical headers and TLS posture to avoid detection
- Runs entirely on your machine; stdio transport with no network exposure
Setup
Prerequisites
- Bun 1.1 or later
- Python 3.10 or later (plus UV if you want to follow the Python tooling in
CLAUDE.md) - A Hey.com account
- Platform: developed and tested on macOS and Linux. Windows users will likely need WSL — pywebview's Windows backend is not currently exercised.
Installation
Clone this repository
git clone https://github.com/Sealjay/mcp-hey.git cd mcp-heyInstall dependencies
bun install uv pip install -r auth/requirements.txtFirst run — authenticate
bun run dev- A system webview opens with Hey.com's login page. Log in normally.
- The helper captures session cookies to
data/hey-cookies.json(permissions600) and exits. - Press Ctrl+C — your MCP client will launch its own server instance from here on.
- Subsequent runs reuse the stored session until it expires.
MCP client configuration
All clients below use the same command/args shape. On macOS, you'll almost certainly need the absolute path to bun — see macOS: bun PATH below.
Claude Code
The quickest route is the CLI:
claude mcp add --transport stdio hey --scope user -- bun run /absolute/path/to/mcp-hey/src/index.ts
The server is available immediately in the current session.
Alternatively, add to .mcp.json at your project root (or ~/.claude.json for a user-scoped server):
{
"mcpServers": {
"hey": {
"type": "stdio",
"command": "bun",
"args": ["run", "/absolute/path/to/mcp-hey/src/index.ts"]
}
}
}
If you edit the file directly, restart the Claude Code session to pick it up.
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"hey": {
"command": "bun",
"args": ["run", "/absolute/path/to/mcp-hey/src/index.ts"]
}
}
}
Restart Claude Desktop. You should see hey listed as an available integration.
Cursor
Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"hey": {
"command": "bun",
"args": ["run", "/absolute/path/to/mcp-hey/src/index.ts"]
}
}
}
Restart Cursor.
Docker
A Dockerfile is included for containerised deployments and Glama compatibility.
Build the image:
docker build -t mcp-hey .
Smoke-test the server (should return a JSON-RPC response listing available tools):
printf '{"jsonrpc":"2.0","id":1,"method":"tools/list"}\n' | docker run -i mcp-hey
Note: The Docker image runs the MCP server only. The Python auth helper and webview login are not available inside the container. You must provide pre-existing session cookies via a volume mount to
data/hey-cookies.jsonfor authenticated operations.
macOS: bun PATH
GUI apps (Claude Desktop, Cursor) and shells launched by Claude Code don't always inherit the PATH from your interactive terminal, so a Homebrew-installed bun may fail with spawn bun ENOENT or simply never connect. Fix by using the absolute path to bun in command:
- Apple Silicon Homebrew —
/opt/homebrew/bin/bun - Intel Homebrew —
/usr/local/bin/bun - Manual install — run
which bunin your terminal to find it
Example:
{
"mcpServers": {
"hey": {
"command": "/opt/homebrew/bin/bun",
"args": ["run", "/absolute/path/to/mcp-hey/src/index.ts"]
}
}
}
Architecture
| Component | Description |
|---|---|
| MCP server | Bun/TypeScript, stdio transport, ~30 MB idle memory |
| Auth helper | Python/pywebview, spawns on-demand for login via system webview |
| Cache | Local SQLite store for messages, threads, and search index |
| Communication | File-based session sharing via data/hey-cookies.json |
Data flow
- MCP client (Claude Code, Claude Desktop, Cursor, etc.) launches
bun run src/index.tsover stdio. - On startup the server validates
data/hey-cookies.json. If missing or expired it spawnsauth/hey-auth.py, which opens Hey in a system webview and writes fresh cookies. - Tool calls hit Hey.com directly with browser-realistic headers; responses are parsed (HTML via
node-html-parser) and cached in SQLite. - Write operations fetch a fresh CSRF token before submitting.
Project structure
mcp-hey/
src/
index.ts # MCP server entry point
hey-client.ts # HTTP client with cookie injection
session.ts # Session management and validation
errors.ts # Error classes and sanitisation
cache/ # SQLite cache (db, schema, messages, search)
tools/ # MCP tool implementations
read.ts # Reading and listing
send.ts # Send, reply, forward
organise.ts # Triage, labels, bubble up, etc.
http-helpers.ts # Shared CSRF retry and endpoint fallback
attachments.ts # Download attachments, parse calendar invites
__tests__/ # Test suites
auth/
hey-auth.py # Python auth helper (pywebview)
requirements.txt
data/
hey-cookies.json # Session storage (gitignored, chmod 600)
docs/
API.md # Hey.com API surface documentation
TOOLS.md # MCP tool reference (34 tools)
hey-features-doc.md # Hey.com feature mapping
Available tools
34 tools grouped by function. See docs/TOOLS.md for parameters, return shapes, and error behaviour.
| Category | Tools |
|---|---|
| Read | hey_list_emails (imbox, feed, paper_trail, trash, spam, drafts, sent), hey_imbox_summary, hey_list_set_aside, hey_list_reply_later, hey_list_screener, hey_read_email, hey_download_attachment, hey_get_calendar_invite |
| Labels & Collections | hey_list_labels, hey_list_label_emails, hey_label, hey_list_collections, hey_list_collection_emails, hey_collection |
| Send | hey_send_email, hey_reply, hey_forward |
| Triage | hey_set_aside, hey_unset_aside, hey_reply_later, hey_remove_reply_later, hey_move_to, hey_set_status, hey_mark_unseen, hey_mark_seen, hey_read_status, hey_thread_mute |
| Bubble up | hey_bubble_up, hey_bubble_up_if_no_reply, hey_pop_bubble |
| Screener | hey_screen, hey_screen_by_id |
| Search | hey_search |
| Cache | hey_cache_status |
Privacy and security
- No credentials are ever stored — only session cookies, written with
600permissions. - Authentication happens entirely inside Hey's own login page (system webview).
- All data stays on your machine. No telemetry is emitted by this project.
- MCP uses stdio transport — the server never opens a network listener.
- Session validity is checked on startup and before sensitive operations.
See SECURITY.md for how to report vulnerabilities.
Limitations
- Prompt-injection risk: as with many MCP servers, this one is subject to the lethal trifecta. A malicious email arriving in your inbox could attempt to instruct Claude to exfiltrate other messages. Treat the tool surface accordingly and review risky actions before approving them.
- Unofficial API: Hey.com's frontend can change without notice and break things. Expect occasional breakage and check
docs/API.mdfor known deltas. - No real-time notifications: polling only.
- Attachment uploads are not yet supported.
- Single account per MCP server instance.
- Account risk: aggressive or abnormal access patterns could in theory trigger Hey's anti-abuse systems. The server respects
x-ratelimitheaders and backs off exponentially, but there are no guarantees. - English UI only: the server parses Hey.com's HTML responses and matches English-language strings (e.g. "You ignored this thread", label names, button text). It will not work correctly if Hey.com is set to a non-English locale.
Troubleshooting
- Auth webview does not open — confirm Python 3.10+ is on
PATHanduv pip install -r auth/requirements.txtsucceeded. On Linux ensure a webview backend is available (python -c "import webview"should not error). 401/403responses after weeks of use — your Hey session has expired. Deletedata/hey-cookies.jsonand runbun run devagain to re-auth.- Rate limits (
429) — the client respectsx-ratelimitheaders and backs off. If you see sustained 429s, reduce concurrent tool use or wait a few minutes. - MCP client can't launch the server —
argsmust be an absolute path, not relative. Ifbunitself fails withspawn bun ENOENT, see macOS:bunPATH. - Cookie name changed — Hey has renamed session cookies before (e.g.
_hey_session→session_token, seedocs/API.mdchangelog). If auth silently fails after a Hey update, capture fresh cookies and compare.
Contributing
Contributions welcome via pull request. Please:
- Use conventional commits (
feat,fix,docs,refactor,test,perf,cicd,revert,WIP). - Run
bun run formatandbun run lintbefore pushing (powered by Biome). - Ensure
bun testpasses. - Update
docs/API.mdif you discover or change any Hey.com API behaviour.
See CLAUDE.md for the full development workflow.
Licence
MIT Licence — see LICENCE.
| 1 | # mcp-hey |
| 2 | |
| 3 | [![Sealjay/mcp-hey MCP server]](https://glama.ai/mcp/servers/Sealjay/mcp-hey) |
| 4 | [![Bun]](https://bun.sh) |
| 5 | [![TypeScript]](https://www.typescriptlang.org/) |
| 6 | [![Python]](https://www.python.org/) |
| 7 | [![MCP]](https://modelcontextprotocol.io/) |
| 8 | [![License: MIT]](LICENCE) |
| 9 | [![GitHub issues]](https://github.com/Sealjay/mcp-hey/issues) |
| 10 | [![GitHub stars]](https://github.com/Sealjay/mcp-hey) |
| 11 | |
| 12 | > A local Model Context Protocol (MCP) server that gives Claude read/write access to your [Hey.com] inbox via reverse-engineered web APIs. |
| 13 | |
| 14 | mcp-hey has two moving parts: a Bun/TypeScript MCP server that exposes Hey tools over stdio, and a small Python helper that uses the system webview to capture session cookies at login. Everything runs locally — no cloud relay, no credentials stored, just session cookies on disk. |
| 15 | |
| 16 | > **Warning — unofficial API.** Hey.com does not publish a public API; mcp-hey reverse-engineers its web endpoints and pairs them with browser-identical HTTP requests. Things can break without notice. The current documented surface lives in [`docs/API.md`]. |
| 17 | |
| 18 | ## Features |
| 19 | |
| 20 | Read emails from Imbox, Feed, Paper Trail, Set Aside, Reply Later, Drafts, Trash, and Spam |
| 21 | Download attachments and parse calendar invites from emails |
| 22 | Send and reply to email threads |
| 23 | Search emails across boxes |
| 24 | Organise mail (set aside, reply later, screen in/out, bubble up) |
| 25 | Local SQLite cache for faster repeated reads and full-text search |
| 26 | Lightweight — around 30 MB idle memory |
| 27 | Browser-identical headers and TLS posture to avoid detection |
| 28 | Runs entirely on your machine; stdio transport with no network exposure |
| 29 | |
| 30 | ## Setup |
| 31 | |
| 32 | ### Prerequisites |
| 33 | |
| 34 | [Bun] 1.1 or later |
| 35 | Python 3.10 or later (plus [UV] if you want to follow the Python tooling in [`CLAUDE.md`]) |
| 36 | A Hey.com account |
| 37 | **Platform**: developed and tested on macOS and Linux. Windows users will likely need WSL — pywebview's Windows backend is not currently exercised. |
| 38 | |
| 39 | ### Installation |
| 40 | |
| 41 | **Clone this repository** |
| 42 | |
| 43 | |
| 44 | git clone https://github.com/Sealjay/mcp-hey.git |
| 45 | cd mcp-hey |
| 46 | |
| 47 | |
| 48 | **Install dependencies** |
| 49 | |
| 50 | |
| 51 | bun install |
| 52 | uv pip install -r auth/requirements.txt |
| 53 | |
| 54 | |
| 55 | **First run — authenticate** |
| 56 | |
| 57 | |
| 58 | bun run dev |
| 59 | |
| 60 | |
| 61 | A system webview opens with Hey.com's login page. Log in normally. |
| 62 | The helper captures session cookies to `data/hey-cookies.json` (permissions `600`) and exits. |
| 63 | Press Ctrl+C — your MCP client will launch its own server instance from here on. |
| 64 | Subsequent runs reuse the stored session until it expires. |
| 65 | |
| 66 | ## MCP client configuration |
| 67 | |
| 68 | All clients below use the same `command`/`args` shape. On macOS, you'll almost certainly need the absolute path to `bun` — see [macOS: `bun` PATH] below. |
| 69 | |
| 70 | ### Claude Code |
| 71 | |
| 72 | The quickest route is the CLI: |
| 73 | |
| 74 | |
| 75 | claude mcp add --transport stdio hey --scope user -- bun run /absolute/path/to/mcp-hey/src/index.ts |
| 76 | |
| 77 | |
| 78 | The server is available immediately in the current session. |
| 79 | |
| 80 | Alternatively, add to `.mcp.json` at your project root (or `~/.claude.json` for a user-scoped server): |
| 81 | |
| 82 | |
| 83 | { |
| 84 | "mcpServers": { |
| 85 | "hey": { |
| 86 | "type": "stdio", |
| 87 | "command": "bun", |
| 88 | "args": ["run", "/absolute/path/to/mcp-hey/src/index.ts"] |
| 89 | } |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | |
| 94 | If you edit the file directly, restart the Claude Code session to pick it up. |
| 95 | |
| 96 | ### Claude Desktop |
| 97 | |
| 98 | Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS): |
| 99 | |
| 100 | |
| 101 | { |
| 102 | "mcpServers": { |
| 103 | "hey": { |
| 104 | "command": "bun", |
| 105 | "args": ["run", "/absolute/path/to/mcp-hey/src/index.ts"] |
| 106 | } |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | |
| 111 | Restart Claude Desktop. You should see `hey` listed as an available integration. |
| 112 | |
| 113 | ### Cursor |
| 114 | |
| 115 | Add to `~/.cursor/mcp.json`: |
| 116 | |
| 117 | |
| 118 | { |
| 119 | "mcpServers": { |
| 120 | "hey": { |
| 121 | "command": "bun", |
| 122 | "args": ["run", "/absolute/path/to/mcp-hey/src/index.ts"] |
| 123 | } |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | |
| 128 | Restart Cursor. |
| 129 | |
| 130 | ### Docker |
| 131 | |
| 132 | A Dockerfile is included for containerised deployments and Glama compatibility. |
| 133 | |
| 134 | **Build the image:** |
| 135 | |
| 136 | |
| 137 | docker build -t mcp-hey . |
| 138 | |
| 139 | |
| 140 | **Smoke-test the server** (should return a JSON-RPC response listing available tools): |
| 141 | |
| 142 | |
| 143 | printf '{"jsonrpc":"2.0","id":1,"method":"tools/list"}\n' | docker run -i mcp-hey |
| 144 | |
| 145 | |
| 146 | > **Note:** The Docker image runs the MCP server only. The Python auth helper and webview login are not available inside the container. You must provide pre-existing session cookies via a volume mount to `data/hey-cookies.json` for authenticated operations. |
| 147 | |
| 148 | ### macOS: `bun` PATH |
| 149 | |
| 150 | GUI apps (Claude Desktop, Cursor) and shells launched by Claude Code don't always inherit the PATH from your interactive terminal, so a Homebrew-installed `bun` may fail with `spawn bun ENOENT` or simply never connect. Fix by using the absolute path to `bun` in `command`: |
| 151 | |
| 152 | **Apple Silicon Homebrew** — `/opt/homebrew/bin/bun` |
| 153 | **Intel Homebrew** — `/usr/local/bin/bun` |
| 154 | **Manual install** — run `which bun` in your terminal to find it |
| 155 | |
| 156 | Example: |
| 157 | |
| 158 | |
| 159 | { |
| 160 | "mcpServers": { |
| 161 | "hey": { |
| 162 | "command": "/opt/homebrew/bin/bun", |
| 163 | "args": ["run", "/absolute/path/to/mcp-hey/src/index.ts"] |
| 164 | } |
| 165 | } |
| 166 | } |
| 167 | |
| 168 | |
| 169 | ## Architecture |
| 170 | |
| 171 | | Component | Description | |
| 172 | |-----------|-------------| |
| 173 | | MCP server | Bun/TypeScript, stdio transport, ~30 MB idle memory | |
| 174 | | Auth helper | Python/pywebview, spawns on-demand for login via system webview | |
| 175 | | Cache | Local SQLite store for messages, threads, and search index | |
| 176 | | Communication | File-based session sharing via `data/hey-cookies.json` | |
| 177 | |
| 178 | ### Data flow |
| 179 | |
| 180 | MCP client (Claude Code, Claude Desktop, Cursor, etc.) launches `bun run src/index.ts` over stdio. |
| 181 | On startup the server validates `data/hey-cookies.json`. If missing or expired it spawns `auth/hey-auth.py`, which opens Hey in a system webview and writes fresh cookies. |
| 182 | Tool calls hit Hey.com directly with browser-realistic headers; responses are parsed (HTML via `node-html-parser`) and cached in SQLite. |
| 183 | Write operations fetch a fresh CSRF token before submitting. |
| 184 | |
| 185 | ### Project structure |
| 186 | |
| 187 | |
| 188 | mcp-hey/ |
| 189 | src/ |
| 190 | index.ts # MCP server entry point |
| 191 | hey-client.ts # HTTP client with cookie injection |
| 192 | session.ts # Session management and validation |
| 193 | errors.ts # Error classes and sanitisation |
| 194 | cache/ # SQLite cache (db, schema, messages, search) |
| 195 | tools/ # MCP tool implementations |
| 196 | read.ts # Reading and listing |
| 197 | send.ts # Send, reply, forward |
| 198 | organise.ts # Triage, labels, bubble up, etc. |
| 199 | http-helpers.ts # Shared CSRF retry and endpoint fallback |
| 200 | attachments.ts # Download attachments, parse calendar invites |
| 201 | __tests__/ # Test suites |
| 202 | auth/ |
| 203 | hey-auth.py # Python auth helper (pywebview) |
| 204 | requirements.txt |
| 205 | data/ |
| 206 | hey-cookies.json # Session storage (gitignored, chmod 600) |
| 207 | docs/ |
| 208 | API.md # Hey.com API surface documentation |
| 209 | TOOLS.md # MCP tool reference (34 tools) |
| 210 | hey-features-doc.md # Hey.com feature mapping |
| 211 | |
| 212 | |
| 213 | ## Available tools |
| 214 | |
| 215 | 34 tools grouped by function. See [`docs/TOOLS.md`] for parameters, return shapes, and error behaviour. |
| 216 | |
| 217 | | Category | Tools | |
| 218 | |----------|-------| |
| 219 | | Read | `hey_list_emails` (imbox, feed, paper_trail, trash, spam, drafts, sent), `hey_imbox_summary`, `hey_list_set_aside`, `hey_list_reply_later`, `hey_list_screener`, `hey_read_email`, `hey_download_attachment`, `hey_get_calendar_invite` | |
| 220 | | Labels & Collections | `hey_list_labels`, `hey_list_label_emails`, `hey_label`, `hey_list_collections`, `hey_list_collection_emails`, `hey_collection` | |
| 221 | | Send | `hey_send_email`, `hey_reply`, `hey_forward` | |
| 222 | | Triage | `hey_set_aside`, `hey_unset_aside`, `hey_reply_later`, `hey_remove_reply_later`, `hey_move_to`, `hey_set_status`, `hey_mark_unseen`, `hey_mark_seen`, `hey_read_status`, `hey_thread_mute` | |
| 223 | | Bubble up | `hey_bubble_up`, `hey_bubble_up_if_no_reply`, `hey_pop_bubble` | |
| 224 | | Screener | `hey_screen`, `hey_screen_by_id` | |
| 225 | | Search | `hey_search` | |
| 226 | | Cache | `hey_cache_status` | |
| 227 | |
| 228 | ## Privacy and security |
| 229 | |
| 230 | No credentials are ever stored — only session cookies, written with `600` permissions. |
| 231 | Authentication happens entirely inside Hey's own login page (system webview). |
| 232 | All data stays on your machine. No telemetry is emitted by this project. |
| 233 | MCP uses stdio transport — the server never opens a network listener. |
| 234 | Session validity is checked on startup and before sensitive operations. |
| 235 | |
| 236 | See [`SECURITY.md`] for how to report vulnerabilities. |
| 237 | |
| 238 | ## Limitations |
| 239 | |
| 240 | **Prompt-injection risk**: as with many MCP servers, this one is subject to [the lethal trifecta]. A malicious email arriving in your inbox could attempt to instruct Claude to exfiltrate other messages. Treat the tool surface accordingly and review risky actions before approving them. |
| 241 | **Unofficial API**: Hey.com's frontend can change without notice and break things. Expect occasional breakage and check [`docs/API.md`] for known deltas. |
| 242 | **No real-time notifications**: polling only. |
| 243 | **Attachment uploads** are not yet supported. |
| 244 | **Single account** per MCP server instance. |
| 245 | **Account risk**: aggressive or abnormal access patterns could in theory trigger Hey's anti-abuse systems. The server respects `x-ratelimit` headers and backs off exponentially, but there are no guarantees. |
| 246 | **English UI only**: the server parses Hey.com's HTML responses and matches English-language strings (e.g. "You ignored this thread", label names, button text). It will not work correctly if Hey.com is set to a non-English locale. |
| 247 | |
| 248 | ## Troubleshooting |
| 249 | |
| 250 | **Auth webview does not open** — confirm Python 3.10+ is on `PATH` and `uv pip install -r auth/requirements.txt` succeeded. On Linux ensure a webview backend is available (`python -c "import webview"` should not error). |
| 251 | **`401`/`403` responses after weeks of use** — your Hey session has expired. Delete `data/hey-cookies.json` and run `bun run dev` again to re-auth. |
| 252 | **Rate limits (`429`)** — the client respects `x-ratelimit` headers and backs off. If you see sustained 429s, reduce concurrent tool use or wait a few minutes. |
| 253 | **MCP client can't launch the server** — `args` must be an absolute path, not relative. If `bun` itself fails with `spawn bun ENOENT`, see [macOS: `bun` PATH]. |
| 254 | **Cookie name changed** — Hey has renamed session cookies before (e.g. `_hey_session` → `session_token`, see [`docs/API.md`] changelog). If auth silently fails after a Hey update, capture fresh cookies and compare. |
| 255 | |
| 256 | ## Contributing |
| 257 | |
| 258 | Contributions welcome via pull request. Please: |
| 259 | |
| 260 | Use conventional commits (`feat`, `fix`, `docs`, `refactor`, `test`, `perf`, `cicd`, `revert`, `WIP`). |
| 261 | Run `bun run format` and `bun run lint` before pushing (powered by [Biome]). |
| 262 | Ensure `bun test` passes. |
| 263 | Update [`docs/API.md`] if you discover or change any Hey.com API behaviour. |
| 264 | |
| 265 | See [`CLAUDE.md`] for the full development workflow. |
| 266 | |
| 267 | ## Licence |
| 268 | |
| 269 | MIT Licence — see [LICENCE]. |
| 270 |
Discussion
Alternatives
Browse more free AI agents or everything in Development.