Repository navigation
Plugin API
Status: experimental. Plugin API v1 is versioned independently of TideMail releases. Breaking protocol changes require a new API version (see compatibility.md).
A TideMail plugin is an external executable.
- TideMail starts it directly: no shell, no arguments.
- TideMail writes one JSON request to its stdin.
- The plugin writes one JSON response to its stdout and exits.
That is the whole integration. There is no Go plugin ABI and no shared library, so any language that can read stdin and write stdout can implement a plugin: Go, Rust, Python, Node, a shell script.
A plugin can:
- classify a message from its metadata (sender, recipients, subject, date, flags; never the body), by hand or automatically for new mail;
- return annotations, short
key=valuefacts such asneeds_reply=trueorcategory=billing, which TideMail stores, shows as tags, and uses for views like Needs You; - declare settings (bool, select, secret) that TideMail shows in a generic form and hands back on every call;
- run as a report: ask TideMail read-only, allowlisted queries (message and thread lists, stored annotations, aggregate analytics such as volume and category counts) and return a report the user reads in TideMail, as text or as a structured view (tiles, sparklines, bars, heatmaps, tables) that TideMail draws in the user's theme colors.
A plugin cannot change mail, send mail, trigger TideMail actions, add UI,
choose colors, or access TideMail's database directly. It reads message
content only if it declares message_raw or message_compose (for
cryptography plugins; see permissions.md). It sees another plugin's annotations only through query.annotations, with
permission. Anything a plugin returns other than annotations is only
displayed.
Annotations are for machines. Presentation is for people. A plugin can return a short human explanation next to its annotations; TideMail shows it in a result card (presentation.md).
Plugins provide semantics. TideMail controls presentation.
Return
category=githuborurgency=high. Nevercolor=purple,style=pill, orforeground=#ff0000: TideMail ignores such keys, and themes and user settings decide how tags look.
- getting-started.md: build your first plugin in a few minutes, from an empty directory to a tag in TideMail's message list.
-
developer-tools.md: use TideMail's headless
plugin scaffold,plugin validate, andplugin testcommands. - The reference:
| Page | Covers |
|---|---|
| manifest.md |
plugin.toml: every field, where plugins live, discovery rules |
| protocol.md | request/response envelopes, methods, metadata fields, errors, stdout/stderr |
| permissions.md | what each permission allows, and what it does not |
| presentation.md | explaining results to people: title, facts, reasons; the result card and its fallback |
| annotations.md | returning annotations, limits, replace-on-success, conventional keys, reclassification |
| events.md |
message.received: automatic processing of new mail |
| settings.md | bool/select/secret settings, storage, secrets, plugin.test
|
| queries.md |
report.run: rounds, read-only queries, fields, scopes, pagination, limits |
| analytics.md | aggregate statistics: volume, categories, attention, response times, contacts |
| views.md | structured report views: tiles, sparklines, bars, heatmaps, tables, drawn in the user's theme |
| security.md | the trust model and every runtime restriction |
| distribution.md | the official catalog: release layout, catalog.json, and how TideMail installs |
| compatibility.md | what API v1 promises, and what may change |
Complete, tested examples live in
examples/plugins/example/ (message
metadata and annotations) and
examples/plugins/analytics/ (a report
built from aggregate analytics).
Manual run (Run plugin in the command palette):
TideMail
│
│ safe metadata (JSON request on stdin)
▼
plugin executable
│
│ JSON response (stdout)
▼
protocol validation api, type, request_id, ok/error, one JSON value, size
│
▼
permission / annotation message_metadata + annotations declared?
validation whole set valid? (all or nothing)
│
▼
annotation storage replaces this plugin's set for this message
│
▼
TideMail UI tags in message rows, Needs You, Message annotations
Annotations are recommendations. TideMail may apply a local user correction
for the conventional semantic fields; re-running the plugin does not clear
that correction, and the correction is never sent back to the plugin or to a
remote classifier with message metadata. Report plugins can read the current
effective value, marked as the user's, only through query.classification
(queries.md).
Automatic run (new mail, when the plugin declares message.received and the
user switches it on):
mail sync
→ event queue per plugin, bounded, deduplicated
→ plugin process same request, one process per plugin at a time
→ validation same checks as a manual run
→ annotation storage same replace-on-success rule
→ live UI update tags and Needs You refresh as results arrive
In ~/.config/tidemail/plugins/ (more precisely
$XDG_CONFIG_HOME/tidemail/plugins/), one directory per plugin, each with a
plugin.toml and the executable it names. TideMail looks for plugins at
startup; restart it after installing or updating one. See
manifest.md.
Users find plugins in the command palette (:): Plugins (experimental),
Run plugin…, and Message annotations. Reports run with enter on the
plugin in Plugins (experimental). The user guide describes them:
guide.md › Plugins.