hypermail-mcp 0.7.14 → 0.7.16

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,23 @@
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.16** — Hardened `draft_email` after successful draft creation:
7
+ > if post-save readback fails, the tool now returns the created draft ID with
8
+ > `warning` and `draftReadbackError` instead of losing the draft behind an
9
+ > error. Compose operations also emit sanitized `HYPERMAIL_DEBUG` stage logs,
10
+ > IMAP drafts now use the server-advertised `\\Drafts` mailbox when present,
11
+ > and the CLI supports `--version`.
12
+ >
13
+ > **v0.7.15** — Hardened IMAP draft creation: drafts now append directly to
14
+ > the Drafts mailbox, retry without the `\\Draft` flag when an IMAP server
15
+ > rejects flagged APPEND, and preserve IMAP reply/forward context in drafts the
16
+ > same way `send_email` does. IMAP operations for a single account are serialized
17
+ > to avoid shared-connection races, and IMAP write failures now include safe
18
+ > server response details instead of only `Command failed`. Account setup
19
+ > responses no longer expose stored provider tokens/passwords. Also rejects
20
+ > multiline plain text passed as `format: "html"`, and adds the Hermes
21
+ > `get_new_emails` poller example.
22
+ >
6
23
  > **v0.7.14** — Added opt-in `HYPERMAIL_DEBUG` structured stderr logs with
7
24
  > redaction for server startup, account-store locking/checkpoint writes, and
8
25
  > `get_new_emails` candidate/claim flow. Hardened Outlook `edit_draft` body
@@ -195,7 +212,7 @@ Hypermail uses flat `HYPERMAIL_*` environment variables as the source of truth.
195
212
  There is no runtime config file. CLI flags only override transport, host, port,
196
213
  and data directory for a single invocation.
197
214
 
198
- CLI flags: `--http`, `--port`, `--host`, `--data-dir`, `--help`.
215
+ CLI flags: `--http`, `--port`, `--host`, `--data-dir`, `--version`, `--help`.
199
216
 
200
217
  Subcommands: `hypermail-mcp generate-key` — generate a base64 32-byte key for
201
218
  `HYPERMAIL_KEY`.
@@ -260,8 +277,8 @@ account store.
260
277
  | Tool | Inputs | Notes |
261
278
  | --- | --- | --- |
262
279
  | `list_accounts` | — | Returns registered emails + provider, no secrets. |
263
- | `add_account` | `provider`, `email?`, `config?` | Starts the provider add flow. Outlook returns a device code; Gmail returns an OAuth URL. Returns `{handle, verification:{type, userCode, verificationUri, expiresAt, message}}`. |
264
- | `complete_add_account` | `provider`, `handle`, `authorizationResponse?`, `code?`, `state?` | Returns `pending` / `ready` / `expired` / `error`. Gmail accepts a pasted final redirected URL or raw code/state for remote-safe completion. |
280
+ | `add_account` | `provider`, `email?`, `config?` | Starts the provider add flow. Outlook returns a device code; Gmail returns an OAuth URL. Ready account responses include public metadata only and never return stored tokens/passwords. Returns `{handle, verification:{type, userCode, verificationUri, expiresAt, message}}` for pending flows. |
281
+ | `complete_add_account` | `provider`, `handle`, `authorizationResponse?`, `code?`, `state?` | Returns `pending` / `ready` / `expired` / `error`. Ready account responses include public metadata only and never return stored tokens/passwords. Gmail accepts a pasted final redirected URL or raw code/state for remote-safe completion. |
265
282
  | `get_account_settings` | `account` | Get signature (HTML) and style preferences for an account. |
266
283
  | `set_account_settings` | `account`, `signature?`, `signaturePath?`, `style?` | Set signature HTML (inline or via file path) and font preferences. |
267
284
  | `remove_account` | `email` | Deletes tokens for the account. |
@@ -273,9 +290,9 @@ account store.
273
290
  | `archive_email` | `account`, `id` | Move a message to the Archive folder. |
274
291
  | `trash_email` | `account`, `id` | Move a message to Deleted Items (trash). |
275
292
  | `move_email` | `account`, `id`, `destination` | Move to any folder by well-known name (`inbox`, `drafts`, etc.) or custom folder ID. |
276
- | `send_email` | `account`, `to[]`, `cc?`, `bcc?`, `subject`, `body`, `format`, `include_signature`, `inReplyTo`, `replyAll?`, `forwardMessageId?`, `attachments?` | Send an email. `format` (`"html"` or `"markdown"`) controls body format — Markdown is converted to HTML via `marked`. Appends signature when `include_signature` is true. `inReplyTo` sends as threaded reply; `forwardMessageId` sends as forward. `inReplyTo` is required — set to `false` for new emails. `attachments` is an optional array of `{filePath, name?}` — files are read from disk and encoded automatically. |
277
- | `draft_email` | `account`, `to[]`, `cc?`, `bcc?`, `subject`, `body`, `format`, `include_signature`, `inReplyTo`, `replyAll?`, `forwardMessageId?`, `attachments?` | Save as draft instead of sending. Same params as `send_email` including `attachments`. Returns the draft message ID and HTML body (`draftHtml`). `inReplyTo` is required — set to `false` for new emails. |
278
- | `edit_draft` | `account`, `id`, `to?`, `cc?`, `bcc?`, `subject?`, `old_text?`, `new_text?`, `body?`, `format?`, `include_signature?`, `new_attachments?`, `remove_attachments?` | Edit an existing draft by ID. Body edits require exact selected-section replacement: copy `old_text` from the current draft HTML (`draftHtml` or `read_email` with `format: "html"`) and provide `new_text`; the match must occur exactly once, and unselected content such as reply/forward history is preserved. Deprecated `body` is only an alias for `new_text` when `old_text` is also provided; body-only full replacement is rejected. Body edits are re-read after saving; if the updated body is not observable after retries, the tool returns an error instead of reporting success. `new_attachments` adds files (`{filePath, name?}[]`); `remove_attachments` removes by attachment ID (`string[]`). Returns the updated draft ID, HTML body (`draftHtml`), and attachment metadata. |
293
+ | `send_email` | `account`, `to[]`, `cc?`, `bcc?`, `subject`, `body`, `format`, `include_signature`, `inReplyTo`, `replyAll?`, `forwardMessageId?`, `attachments?` | Send an email. `format` (`"html"` or `"markdown"`) controls body format — Markdown is converted to HTML via `marked`; multiline plain text with `format: "html"` is rejected, so use `"markdown"` for paragraphs or add tags like `<p>`/`<br>`. Appends signature when `include_signature` is true. `inReplyTo` sends as threaded reply; `forwardMessageId` sends as forward. `inReplyTo` is required — set to `false` for new emails. `attachments` is an optional array of `{filePath, name?}` — files are read from disk and encoded automatically. |
294
+ | `draft_email` | `account`, `to[]`, `cc?`, `bcc?`, `subject`, `body`, `format`, `include_signature`, `inReplyTo`, `replyAll?`, `forwardMessageId?`, `attachments?` | Save as draft instead of sending. Same params as `send_email` including `attachments`. Returns the draft message ID and, when readback succeeds, HTML body (`draftHtml`). If the draft is created but readback fails, returns the draft ID with `warning` and `draftReadbackError` so callers can retry `read_email` or continue with `send_draft`. `inReplyTo` is required — set to `false` for new emails. |
295
+ | `edit_draft` | `account`, `id`, `to?`, `cc?`, `bcc?`, `subject?`, `old_text?`, `new_text?`, `body?`, `format?`, `include_signature?`, `new_attachments?`, `remove_attachments?` | Edit an existing draft by ID. Body edits require exact selected-section replacement: copy `old_text` from the current draft HTML (`draftHtml` or `read_email` with `format: "html"`) and provide `new_text`; the match must occur exactly once, and unselected content such as reply/forward history is preserved. Deprecated `body` is only an alias for `new_text` when `old_text` is also provided; body-only full replacement is rejected. Multiline plain-text replacements with `format: "html"` are rejected; use `"markdown"` for paragraphs or add tags like `<p>`/`<br>`. Body edits are re-read after saving; if the updated body is not observable after retries, the tool returns an error instead of reporting success. `new_attachments` adds files (`{filePath, name?}[]`); `remove_attachments` removes by attachment ID (`string[]`). Returns the updated draft ID, HTML body (`draftHtml`), and attachment metadata. |
279
296
  | `send_draft` | `account`, `id` | Send an existing draft email by ID. Use with draft IDs returned by `draft_email` or `edit_draft`. |
280
297
  | `list_folders` | `account`, `parentFolderId?` | List available mail folders. Returns top-level folders by default, or children of `parentFolderId`. |
281
298
  | `create_folder` | `account`, `displayName`, `parentFolderId?` | Create a new mail folder under root (default) or the given parent. |
@@ -307,6 +324,9 @@ tool on their own schedule, for example every 30–60 seconds.
307
324
  All-account calls return partial failures as `errors: [{ account, message }]`
308
325
  and still return successful accounts' emails.
309
326
 
327
+ See [`examples/hermes/`](examples/hermes/) for a Hermes scheduler integration
328
+ that polls this tool and hands new-email payloads to a Hermes agent.
329
+
310
330
  ## Add-account flows
311
331
 
312
332
  ### Outlook