hypermail-mcp 0.7.8 → 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,10 @@
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
+ >
6
10
  > **v0.7.8** — Default Gmail loopback redirect URI changed from random-port
7
11
  > `/oauth2callback` to fixed `http://127.0.0.1:33333/callback` (still overridable via
8
12
  > `HYPERMAIL_GMAIL_REDIRECT_URI`). `.data/` encryption key directory added to
@@ -23,8 +27,7 @@ inboxes through a single, unified tool surface.
23
27
  > (`attachments` param). `edit_draft` gains `new_attachments` and
24
28
  > `remove_attachments` — `add_attachment_to_draft` is removed (23 tools now).
25
29
  > Draft editing uses multi-strategy thread boundary detection for more reliable
26
- > quoted-thread preservation. Watcher now supports shell-command notification
27
- > alongside webhook delivery. Published CLI installs the MCP SDK dependency so
30
+ > quoted-thread preservation. Published CLI installs the MCP SDK dependency so
28
31
  > global/npx runs do not fail on a missing SDK module.
29
32
  >
30
33
  > **v0.7.4** — `inReplyTo` is now a required parameter on `send_email` and
@@ -40,12 +43,7 @@ inboxes through a single, unified tool surface.
40
43
  > **v0.7.1** — Every config field is now settable via a dedicated
41
44
  > `HYPERMAIL_*` env var. Legacy provider env vars are no longer accepted. See
42
45
  > [Environment Variables](#environment-variables) for the full reference.
43
- >
44
- > **v0.7.0** — Email watch mode: background poll loop detects new inbox
45
- > messages and POSTs them to a configurable webhook URL (e.g. Mastra). Opt-in —
46
- > disabled by default, enabled via `HYPERMAIL_WATCH_ENABLED=true`.
47
- > Works in both stdio and HTTP transport modes.
48
- >
46
+
49
47
  > **v0.6.3** — Unify stdio and HTTP modes into a single feature set. Removed
50
48
  > email watch (inbox polling, SSE push, notification buffer), agent
51
49
  > multi-tenancy (`agents.yaml`, `x-api-key` auth, per-agent allowlists), and
@@ -216,15 +214,6 @@ hypermail-mcp
216
214
  | `HYPERMAIL_GMAIL_REDIRECT_URI` | Hosted Gmail OAuth callback URI | Local loopback callback when unset |
217
215
  | `HYPERMAIL_TOOLS_ENABLED` | Comma-separated tool allowlist | Empty/unset means no filtering |
218
216
  | `HYPERMAIL_TOOLS_DISABLED` | Comma-separated tool blocklist | Empty/unset means no filtering |
219
- | `HYPERMAIL_WATCH_ENABLED` | Enable inbox polling: `true` or `false` | `false` |
220
- | `HYPERMAIL_WATCH_POLL_SECONDS` | Watcher polling cadence | `10` |
221
- | `HYPERMAIL_WATCH_WEBHOOK_URL` | Webhook delivery target | Required if watch is enabled and no notify command is set |
222
- | `HYPERMAIL_WATCH_WEBHOOK_RETRY_ATTEMPTS` | Webhook retry attempts | `5` |
223
- | `HYPERMAIL_WATCH_WEBHOOK_RETRY_DELAY_MS` | Webhook exponential-backoff base delay | `1000` |
224
- | `HYPERMAIL_WATCH_NOTIFY_COMMAND` | Shell command run with `EmailFull` JSON on stdin | Required if watch is enabled and no webhook is set |
225
- | `HYPERMAIL_WATCH_NOTIFY_TIMEOUT_MS` | Notify-command execution timeout | `30000` |
226
- | `HYPERMAIL_WATCH_NOTIFY_RETRY_ATTEMPTS` | Notify-command retry attempts | `5` |
227
- | `HYPERMAIL_WATCH_NOTIFY_RETRY_DELAY_MS` | Notify-command exponential-backoff base delay | `1000` |
228
217
 
229
218
  **Priority order:** selected CLI flags > `HYPERMAIL_*` env vars > hardcoded defaults.
230
219
 
@@ -247,6 +236,7 @@ account store.
247
236
  | `set_account_settings` | `account`, `signature?`, `signaturePath?`, `style?` | Set signature HTML (inline or via file path) and font preferences. |
248
237
  | `remove_account` | `email` | Deletes tokens for the account. |
249
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. |
250
240
  | `search_emails` | `account`, `query`, `limit?` | KQL on Outlook. |
251
241
  | `read_email` | `account`, `id`, `format?` | Returns full body + recipients + attachment metadata. `format`: `markdown` (default), `html`, or `text`. |
252
242
  | `read_attachment` | `account`, `messageId`, `attachmentId` | Download an attachment to a temporary file and return its path. |
@@ -264,44 +254,28 @@ account store.
264
254
  | `mark_read` | `account`, `id` | Mark a message as read. |
265
255
  | `mark_unread` | `account`, `id` | Mark a message as unread. |
266
256
 
267
- ## Email Watch
268
-
269
- When enabled, hypermail-mcp runs a background poll loop that scans inboxes for
270
- new messages and delivers each one via webhook POST and/or shell command.
271
- Intended for push-based email triage — downstream agents receive full email
272
- content without polling.
273
-
274
- ```bash
275
- HYPERMAIL_WATCH_ENABLED=true \
276
- HYPERMAIL_WATCH_POLL_SECONDS=10 \
277
- HYPERMAIL_WATCH_WEBHOOK_URL=http://localhost:3000/api/email-webhook \
278
- HYPERMAIL_WATCH_NOTIFY_COMMAND='node /path/to/email-handler.js' \
279
- hypermail-mcp
280
- ```
257
+ ## Pull new emails
281
258
 
282
- **Validation:** If `HYPERMAIL_WATCH_ENABLED=true`, startup requires at least one
283
- of `HYPERMAIL_WATCH_WEBHOOK_URL` or `HYPERMAIL_WATCH_NOTIFY_COMMAND`. Webhook
284
- URLs are syntax-validated, and notify commands must be non-empty. Startup does
285
- 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.
286
262
 
287
263
  **Behavior:**
288
- - Polls **all accounts** in the store, **inbox only**.
289
- - Detects new emails via `lastSeenIds` (capped at 200) stored in the encrypted
290
- account file no duplicate emits across restarts.
291
- - Two delivery modes (can be used together):
292
- - **Webhook:** One `POST` per email (full body as `EmailFull` JSON).
293
- - **Notify command:** Executes `HYPERMAIL_WATCH_NOTIFY_COMMAND` through the
294
- platform shell with the `EmailFull` JSON piped to stdin.
295
- - Both modes use exponential backoff (`baseDelay × 2^attempt`). Retries on
296
- failures (non-2xx for webhook, non-zero exit for command). Logs and moves on
297
- after `maxAttempts` exhausted never blocks the poll loop.
298
- - Command delivery is fire-and-forget the poll loop continues while delivery
299
- runs in the background.
300
- - Works in both **stdio** and **HTTP** transport modes — the poll interval
301
- fires normally alongside MCP message handling.
302
-
303
- **Rate limits:** Polling every 10s on a single inbox = 6 req/min = 0.6% of
304
- 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.
305
279
 
306
280
  ## Add-account flows
307
281
 
@@ -407,15 +381,11 @@ src/
407
381
  client.ts # Gmail API (googleapis)
408
382
  index.ts # GmailProvider implementation
409
383
  shared/ # shared utilities across providers
410
- watcher/
411
- manager.ts # WatcherManager — inbox poll loop + dedup
412
- webhook.ts # HTTP POST with exponential backoff retry
413
- script.ts # shell-command delivery with retry/timeout
414
- index.ts # barrel export
415
384
  tools/
416
385
  index.ts # MCP tool registrations
417
386
  accounts.ts # list/add/remove/complete-add account tools
418
387
  browse.ts # list/search/read email tools
388
+ new-emails.ts # get_new_emails pull/checkpoint tool
419
389
  compose.ts # send/draft/edit/send-draft tools
420
390
  folders.ts # list/create/delete/rename folder tools
421
391
  organize.ts # archive/trash/move/mark-read/mark-unread tools