MCP hey agent

MCP server for Hey.com: read, send, search, and organise email from Claude or any MCP client.

by Sealjay·MIT license·★ 13 Stars on the repo·GitHub ↗

Files of MCP hey

Sealjay/main1 file
README.md
Show the full text270 lines

mcp-hey

Sealjay/mcp-hey MCP server Bun TypeScript Python MCP License: MIT GitHub issues GitHub stars

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
  1. Clone this repository

    git clone https://github.com/Sealjay/mcp-hey.git
    cd mcp-hey
    
  2. Install dependencies

    bun install
    uv pip install -r auth/requirements.txt
    
  3. First run — authenticate

    bun run dev
    
    1. A system webview opens with Hey.com's login page. Log in normally.
    2. The helper captures session cookies to data/hey-cookies.json (permissions 600) and exits.
    3. Press Ctrl+C — your MCP client will launch its own server instance from here on.
    4. 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.json for 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 bun in 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
  1. MCP client (Claude Code, Claude Desktop, Cursor, etc.) launches bun run src/index.ts over stdio.
  2. 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.
  3. Tool calls hit Hey.com directly with browser-realistic headers; responses are parsed (HTML via node-html-parser) and cached in SQLite.
  4. 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 600 permissions.
  • 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.md for 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-ratelimit headers 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 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).
  • 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.
  • 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.
  • 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.
  • 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.

Contributing

Contributions welcome via pull request. Please:

  • Use conventional commits (feat, fix, docs, refactor, test, perf, cicd, revert, WIP).
  • Run bun run format and bun run lint before pushing (powered by Biome).
  • Ensure bun test passes.
  • Update docs/API.md if 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/badges/score.svg)](https://glama.ai/mcp/servers/Sealjay/mcp-hey)
4[![Bun](https://img.shields.io/badge/Bun-1.1+-000000?logo=bun&logoColor=ffffff)](https://bun.sh)
5[![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178C6?logo=typescript&logoColor=ffffff)](https://www.typescriptlang.org/)
6[![Python](https://img.shields.io/badge/Python-3.10+-3776AB?logo=python&logoColor=ffffff)](https://www.python.org/)
7[![MCP](https://img.shields.io/badge/MCP-Model_Context_Protocol-6E44FF)](https://modelcontextprotocol.io/)
8[![License: MIT](https://img.shields.io/github/license/Sealjay/mcp-hey)](LICENCE)
9[![GitHub issues](https://img.shields.io/github/issues/Sealjay/mcp-hey)](https://github.com/Sealjay/mcp-hey/issues)
10[![GitHub stars](https://img.shields.io/github/stars/Sealjay/mcp-hey?style=social)](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](https://hey.com) inbox via reverse-engineered web APIs.
13 
14mcp-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`](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](https://bun.sh) 1.1 or later
35- Python 3.10 or later (plus [UV](https://docs.astral.sh/uv/) if you want to follow the Python tooling in [`CLAUDE.md`](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 
411. **Clone this repository**
42 
43 ```bash
44 git clone https://github.com/Sealjay/mcp-hey.git
45 cd mcp-hey
46 ```
47 
482. **Install dependencies**
49 
50 ```bash
51 bun install
52 uv pip install -r auth/requirements.txt
53 ```
54 
553. **First run — authenticate**
56 
57 ```bash
58 bun run dev
59 ```
60 
61 1. A system webview opens with Hey.com's login page. Log in normally.
62 2. The helper captures session cookies to `data/hey-cookies.json` (permissions `600`) and exits.
63 3. Press Ctrl+C — your MCP client will launch its own server instance from here on.
64 4. Subsequent runs reuse the stored session until it expires.
65 
66## MCP client configuration
67 
68All clients below use the same `command`/`args` shape. On macOS, you'll almost certainly need the absolute path to `bun` — see [macOS: `bun` PATH](#macos-bun-path) below.
69 
70### Claude Code
71 
72The quickest route is the CLI:
73 
74```bash
75claude mcp add --transport stdio hey --scope user -- bun run /absolute/path/to/mcp-hey/src/index.ts
76```
77 
78The server is available immediately in the current session.
79 
80Alternatively, add to `.mcp.json` at your project root (or `~/.claude.json` for a user-scoped server):
81 
82```json
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 
94If you edit the file directly, restart the Claude Code session to pick it up.
95 
96### Claude Desktop
97 
98Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):
99 
100```json
101{
102 "mcpServers": {
103 "hey": {
104 "command": "bun",
105 "args": ["run", "/absolute/path/to/mcp-hey/src/index.ts"]
106 }
107 }
108}
109```
110 
111Restart Claude Desktop. You should see `hey` listed as an available integration.
112 
113### Cursor
114 
115Add to `~/.cursor/mcp.json`:
116 
117```json
118{
119 "mcpServers": {
120 "hey": {
121 "command": "bun",
122 "args": ["run", "/absolute/path/to/mcp-hey/src/index.ts"]
123 }
124 }
125}
126```
127 
128Restart Cursor.
129 
130### Docker
131 
132A Dockerfile is included for containerised deployments and Glama compatibility.
133 
134**Build the image:**
135 
136```bash
137docker build -t mcp-hey .
138```
139 
140**Smoke-test the server** (should return a JSON-RPC response listing available tools):
141 
142```bash
143printf '{"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 
150GUI 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 
156Example:
157 
158```json
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 
1801. MCP client (Claude Code, Claude Desktop, Cursor, etc.) launches `bun run src/index.ts` over stdio.
1812. 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.
1823. Tool calls hit Hey.com directly with browser-realistic headers; responses are parsed (HTML via `node-html-parser`) and cached in SQLite.
1834. Write operations fetch a fresh CSRF token before submitting.
184 
185### Project structure
186 
187```
188mcp-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 
21534 tools grouped by function. See [`docs/TOOLS.md`](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 
236See [`SECURITY.md`](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](https://simonwillison.net/2025/Jun/16/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`](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](#macos-bun-path).
254- **Cookie name changed** — Hey has renamed session cookies before (e.g. `_hey_session` → `session_token`, see [`docs/API.md`](docs/API.md) changelog). If auth silently fails after a Hey update, capture fresh cookies and compare.
255 
256## Contributing
257 
258Contributions 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](https://biomejs.dev/)).
262- Ensure `bun test` passes.
263- Update [`docs/API.md`](docs/API.md) if you discover or change any Hey.com API behaviour.
264 
265See [`CLAUDE.md`](CLAUDE.md) for the full development workflow.
266 
267## Licence
268 
269MIT Licence — see [LICENCE](LICENCE).
270 

Discussion

Alternatives