hypermail-mcp 0.7.7 → 0.7.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,6 +3,15 @@
3
3
  A **Model Context Protocol** server that lets an agent operate any of the user's
4
4
  inboxes through a single, unified tool surface.
5
5
 
6
+ > **v0.7.9** — Replaced server-side email watch/webhook/script delivery with
7
+ > the pull-based `get_new_emails` tool. Agents schedule their own repeated calls
8
+ > and fetch bounded batches of new inbox email.
9
+ >
10
+ > **v0.7.8** — Default Gmail loopback redirect URI changed from random-port
11
+ > `/oauth2callback` to fixed `http://127.0.0.1:33333/callback` (still overridable via
12
+ > `HYPERMAIL_GMAIL_REDIRECT_URI`). `.data/` encryption key directory added to
13
+ > `.gitignore`.
14
+ >
6
15
  > **v0.7.7** — Env-only configuration. Runtime config now comes from flat
7
16
  > `HYPERMAIL_*` environment variables plus selected CLI overrides. Config files
8
17
  > and legacy provider env names are no longer read. Hosted Gmail OAuth callbacks
@@ -18,8 +27,7 @@ inboxes through a single, unified tool surface.
18
27
  > (`attachments` param). `edit_draft` gains `new_attachments` and
19
28
  > `remove_attachments` — `add_attachment_to_draft` is removed (23 tools now).
20
29
  > Draft editing uses multi-strategy thread boundary detection for more reliable
21
- > quoted-thread preservation. Watcher now supports shell-command notification
22
- > alongside webhook delivery. Published CLI installs the MCP SDK dependency so
30
+ > quoted-thread preservation. Published CLI installs the MCP SDK dependency so
23
31
  > global/npx runs do not fail on a missing SDK module.
24
32
  >
25
33
  > **v0.7.4** — `inReplyTo` is now a required parameter on `send_email` and
@@ -35,12 +43,7 @@ inboxes through a single, unified tool surface.
35
43
  > **v0.7.1** — Every config field is now settable via a dedicated
36
44
  > `HYPERMAIL_*` env var. Legacy provider env vars are no longer accepted. See
37
45
  > [Environment Variables](#environment-variables) for the full reference.
38
- >
39
- > **v0.7.0** — Email watch mode: background poll loop detects new inbox
40
- > messages and POSTs them to a configurable webhook URL (e.g. Mastra). Opt-in —
41
- > disabled by default, enabled via `HYPERMAIL_WATCH_ENABLED=true`.
42
- > Works in both stdio and HTTP transport modes.
43
- >
46
+
44
47
  > **v0.6.3** — Unify stdio and HTTP modes into a single feature set. Removed
45
48
  > email watch (inbox polling, SSE push, notification buffer), agent
46
49
  > multi-tenancy (`agents.yaml`, `x-api-key` auth, per-agent allowlists), and
@@ -211,15 +214,6 @@ hypermail-mcp
211
214
  | `HYPERMAIL_GMAIL_REDIRECT_URI` | Hosted Gmail OAuth callback URI | Local loopback callback when unset |
212
215
  | `HYPERMAIL_TOOLS_ENABLED` | Comma-separated tool allowlist | Empty/unset means no filtering |
213
216
  | `HYPERMAIL_TOOLS_DISABLED` | Comma-separated tool blocklist | Empty/unset means no filtering |
214
- | `HYPERMAIL_WATCH_ENABLED` | Enable inbox polling: `true` or `false` | `false` |
215
- | `HYPERMAIL_WATCH_POLL_SECONDS` | Watcher polling cadence | `10` |
216
- | `HYPERMAIL_WATCH_WEBHOOK_URL` | Webhook delivery target | Required if watch is enabled and no notify command is set |
217
- | `HYPERMAIL_WATCH_WEBHOOK_RETRY_ATTEMPTS` | Webhook retry attempts | `5` |
218
- | `HYPERMAIL_WATCH_WEBHOOK_RETRY_DELAY_MS` | Webhook exponential-backoff base delay | `1000` |
219
- | `HYPERMAIL_WATCH_NOTIFY_COMMAND` | Shell command run with `EmailFull` JSON on stdin | Required if watch is enabled and no webhook is set |
220
- | `HYPERMAIL_WATCH_NOTIFY_TIMEOUT_MS` | Notify-command execution timeout | `30000` |
221
- | `HYPERMAIL_WATCH_NOTIFY_RETRY_ATTEMPTS` | Notify-command retry attempts | `5` |
222
- | `HYPERMAIL_WATCH_NOTIFY_RETRY_DELAY_MS` | Notify-command exponential-backoff base delay | `1000` |
223
217
 
224
218
  **Priority order:** selected CLI flags > `HYPERMAIL_*` env vars > hardcoded defaults.
225
219
 
@@ -242,6 +236,7 @@ account store.
242
236
  | `set_account_settings` | `account`, `signature?`, `signaturePath?`, `style?` | Set signature HTML (inline or via file path) and font preferences. |
243
237
  | `remove_account` | `email` | Deletes tokens for the account. |
244
238
  | `list_emails` | `account`, `folder?`, `limit?`, `unreadOnly?`, `skip?` | Defaults: folder=`inbox`, limit=25. Supports pagination via `skip` — response includes `hasMore`. |
239
+ | `get_new_emails` | `account?`, `limit?` | Pull new inbox emails not previously returned by this tool. `limit` defaults to 10 and is global when `account` is omitted. Returns full markdown bodies with attachment metadata; bodies may be truncated. |
245
240
  | `search_emails` | `account`, `query`, `limit?` | KQL on Outlook. |
246
241
  | `read_email` | `account`, `id`, `format?` | Returns full body + recipients + attachment metadata. `format`: `markdown` (default), `html`, or `text`. |
247
242
  | `read_attachment` | `account`, `messageId`, `attachmentId` | Download an attachment to a temporary file and return its path. |
@@ -259,44 +254,28 @@ account store.
259
254
  | `mark_read` | `account`, `id` | Mark a message as read. |
260
255
  | `mark_unread` | `account`, `id` | Mark a message as unread. |
261
256
 
262
- ## Email Watch
263
-
264
- When enabled, hypermail-mcp runs a background poll loop that scans inboxes for
265
- new messages and delivers each one via webhook POST and/or shell command.
266
- Intended for push-based email triage — downstream agents receive full email
267
- content without polling.
268
-
269
- ```bash
270
- HYPERMAIL_WATCH_ENABLED=true \
271
- HYPERMAIL_WATCH_POLL_SECONDS=10 \
272
- HYPERMAIL_WATCH_WEBHOOK_URL=http://localhost:3000/api/email-webhook \
273
- HYPERMAIL_WATCH_NOTIFY_COMMAND='node /path/to/email-handler.js' \
274
- hypermail-mcp
275
- ```
257
+ ## Pull new emails
276
258
 
277
- **Validation:** If `HYPERMAIL_WATCH_ENABLED=true`, startup requires at least one
278
- of `HYPERMAIL_WATCH_WEBHOOK_URL` or `HYPERMAIL_WATCH_NOTIFY_COMMAND`. Webhook
279
- URLs are syntax-validated, and notify commands must be non-empty. Startup does
280
- not test network reachability or execute the command.
259
+ `get_new_emails` is the replacement for server-side watch/push delivery. The
260
+ server does not run background cron jobs; agents or their harnesses call this
261
+ tool on their own schedule, for example every 30–60 seconds.
281
262
 
282
263
  **Behavior:**
283
- - Polls **all accounts** in the store, **inbox only**.
284
- - Detects new emails via `lastSeenIds` (capped at 200) stored in the encrypted
285
- account file no duplicate emits across restarts.
286
- - Two delivery modes (can be used together):
287
- - **Webhook:** One `POST` per email (full body as `EmailFull` JSON).
288
- - **Notify command:** Executes `HYPERMAIL_WATCH_NOTIFY_COMMAND` through the
289
- platform shell with the `EmailFull` JSON piped to stdin.
290
- - Both modes use exponential backoff (`baseDelay × 2^attempt`). Retries on
291
- failures (non-2xx for webhook, non-zero exit for command). Logs and moves on
292
- after `maxAttempts` exhausted never blocks the poll loop.
293
- - Command delivery is fire-and-forget the poll loop continues while delivery
294
- runs in the background.
295
- - Works in both **stdio** and **HTTP** transport modes — the poll interval
296
- fires normally alongside MCP message handling.
297
-
298
- **Rate limits:** Polling every 10s on a single inbox = 6 req/min = 0.6% of
299
- Microsoft Graph's 10,000 req/10min per-user limit. Safe for personal inboxes.
264
+ - Polls **inbox only**.
265
+ - `account` is optional. When omitted, the tool checks all registered accounts.
266
+ - `limit` defaults to `10`. In all-account mode, the limit is a global total
267
+ across accounts, selected by oldest `receivedAt` first.
268
+ - First use for an account initializes its checkpoint to the newest inbox email
269
+ and returns no emails for that account.
270
+ - Later calls return emails not previously returned by this tool, oldest first.
271
+ - Returned bodies are markdown and may be truncated around 20k characters; call
272
+ `read_email` for the full body when needed.
273
+ - Attachments are returned as metadata only; call `read_attachment` for content.
274
+ - The tool does not mark emails as read.
275
+ - `limit: 0` can initialize/check state without fetching message bodies.
276
+
277
+ All-account calls return partial failures as `errors: [{ account, message }]`
278
+ and still return successful accounts' emails.
300
279
 
301
280
  ## Add-account flows
302
281
 
@@ -402,15 +381,11 @@ src/
402
381
  client.ts # Gmail API (googleapis)
403
382
  index.ts # GmailProvider implementation
404
383
  shared/ # shared utilities across providers
405
- watcher/
406
- manager.ts # WatcherManager — inbox poll loop + dedup
407
- webhook.ts # HTTP POST with exponential backoff retry
408
- script.ts # shell-command delivery with retry/timeout
409
- index.ts # barrel export
410
384
  tools/
411
385
  index.ts # MCP tool registrations
412
386
  accounts.ts # list/add/remove/complete-add account tools
413
387
  browse.ts # list/search/read email tools
388
+ new-emails.ts # get_new_emails pull/checkpoint tool
414
389
  compose.ts # send/draft/edit/send-draft tools
415
390
  folders.ts # list/create/delete/rename folder tools
416
391
  organize.ts # archive/trash/move/mark-read/mark-unread tools