fastmail-cli 1.0.0

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 ADDED
@@ -0,0 +1,127 @@
1
+ # fastmail-cli
2
+
3
+ OpenClaw plugin for Fastmail email, contacts, and calendar. Provides 36 agent tools backed by a persistent in-process MCP connection for token-efficient output (5-7x savings vs raw JSON).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ openclaw plugins install fastmail-cli
9
+ ```
10
+
11
+ ## Prerequisites
12
+
13
+ 1. **Remote MCP Server**: Deploy the [fastmail-mcp-remote](https://github.com/omarshahine/fastmail-mcp-remote) Worker to Cloudflare.
14
+
15
+ 2. **Get a Bearer Token**: Authenticate via the CLI to obtain a token:
16
+
17
+ ```bash
18
+ alias fastmail="npx tsx ~/path/to/fastmail-mcp-remote/cli/main.ts"
19
+ fastmail auth --url https://your-worker.example.com --team myteam
20
+ ```
21
+
22
+ The token is saved to `~/.config/fastmail-cli/config.json`. Copy the `bearerToken` value for plugin configuration.
23
+
24
+ ## Configuration
25
+
26
+ Both fields are **required** in your OpenClaw workspace config:
27
+
28
+ | Key | Description |
29
+ |-----|-------------|
30
+ | `workerUrl` | URL of your deployed Fastmail MCP Worker |
31
+ | `bearerToken` | Bearer token from `fastmail auth` (each user needs their own) |
32
+
33
+ Each workspace can have different credentials, enabling multi-user setups on the same machine.
34
+
35
+ ## Tools
36
+
37
+ ### Email Read (11 tools, always available)
38
+
39
+ - `fastmail_inbox` - Recent inbox emails
40
+ - `fastmail_get_email` - Read a single email
41
+ - `fastmail_search_emails` - Search with text and filters (sender, date, unread, etc.)
42
+ - `fastmail_get_thread` - Conversation thread
43
+ - `fastmail_list_mailboxes` - List mailboxes
44
+ - `fastmail_get_mailbox_stats` - Mailbox statistics
45
+ - `fastmail_get_account_summary` - Account overview
46
+ - `fastmail_list_identities` - Sending identities
47
+ - `fastmail_get_attachments` - Email attachments
48
+ - `fastmail_download_attachment` - Download attachment
49
+ - `fastmail_get_inbox_updates` - Incremental sync
50
+
51
+ ### Email Write (3 tools, optional)
52
+
53
+ - `fastmail_send_email` - Send email
54
+ - `fastmail_create_draft` - Create draft
55
+ - `fastmail_reply_to_email` - Reply to email
56
+
57
+ ### Email Organize (6 tools, optional)
58
+
59
+ - `fastmail_mark_read` - Mark as read
60
+ - `fastmail_mark_unread` - Mark as unread
61
+ - `fastmail_flag` - Flag (star)
62
+ - `fastmail_unflag` - Unflag (unstar)
63
+ - `fastmail_delete` - Delete (trash)
64
+ - `fastmail_move` - Move to mailbox
65
+
66
+ ### Email Bulk (6 tools, optional)
67
+
68
+ - `fastmail_bulk_read` - Bulk mark read
69
+ - `fastmail_bulk_unread` - Bulk mark unread
70
+ - `fastmail_bulk_flag` - Bulk flag
71
+ - `fastmail_bulk_unflag` - Bulk unflag
72
+ - `fastmail_bulk_delete` - Bulk delete
73
+ - `fastmail_bulk_move` - Bulk move
74
+
75
+ ### Contacts (3 tools, always available)
76
+
77
+ - `fastmail_list_contacts` - List contacts
78
+ - `fastmail_get_contact` - Contact details
79
+ - `fastmail_search_contacts` - Search contacts
80
+
81
+ ### Calendar (4 tools, 3 always + 1 optional)
82
+
83
+ - `fastmail_list_calendars` - List calendars
84
+ - `fastmail_list_events` - List events
85
+ - `fastmail_get_event` - Event details
86
+ - `fastmail_create_event` - Create event (optional)
87
+
88
+ ### Memos (3 tools, 1 always + 2 optional)
89
+
90
+ - `fastmail_get_memo` - Get memo on email
91
+ - `fastmail_create_memo` - Add memo (optional)
92
+ - `fastmail_delete_memo` - Delete memo (optional)
93
+
94
+ ## Architecture
95
+
96
+ ```
97
+ Agent -> OpenClaw Plugin -> MCP SDK (in-process) -> Remote Worker -> Fastmail JMAP API
98
+ ```
99
+
100
+ The plugin maintains a persistent MCP connection per workspace:
101
+ 1. Registers OpenClaw tools with JSON Schema parameters
102
+ 2. On first tool call, connects to the remote Worker via MCP SDK with Bearer token auth
103
+ 3. All subsequent calls reuse the same connection (no per-call overhead)
104
+ 4. Responses are formatted in-process using compact text formatters
105
+
106
+ One runtime dependency: `@modelcontextprotocol/sdk`.
107
+
108
+ ## Development
109
+
110
+ ```bash
111
+ # Clone the repo
112
+ git clone https://github.com/omarshahine/fastmail-mcp-remote.git
113
+ cd fastmail-mcp-remote/openclaw-plugin
114
+
115
+ # Install dependencies
116
+ npm install --legacy-peer-deps
117
+
118
+ # Type check
119
+ npx tsc --noEmit
120
+
121
+ # Local test (symlink into OpenClaw extensions)
122
+ ln -s $(pwd) ~/.openclaw/extensions/fastmail-cli
123
+ ```
124
+
125
+ ## License
126
+
127
+ MIT
package/index.ts ADDED
@@ -0,0 +1,58 @@
1
+ /**
2
+ * OpenClaw plugin entry point for Fastmail.
3
+ *
4
+ * Registers 36 agent tools that proxy to the remote Fastmail MCP Worker
5
+ * via a persistent in-process MCP SDK connection. Responses are formatted
6
+ * using compact text formatters for token efficiency.
7
+ *
8
+ * Credentials (workerUrl + bearerToken) come from plugin config,
9
+ * supporting multi-user setups where each workspace has its own token.
10
+ */
11
+
12
+ import { FastmailMcpClient } from "./src/mcp-client.js";
13
+ import { resolveCredentials } from "./src/auth.js";
14
+ import { registerEmailTools } from "./src/tools/email.js";
15
+ import { registerContactTools } from "./src/tools/contacts.js";
16
+ import { registerCalendarTools } from "./src/tools/calendar.js";
17
+ import { registerMemoTools } from "./src/tools/memo.js";
18
+
19
+ /** Minimal typed interface for the OpenClaw plugin API. */
20
+ export interface OpenClawApi {
21
+ registerTool(tool: {
22
+ name: string;
23
+ description: string;
24
+ parameters: Record<string, unknown>;
25
+ execute: (_id: string, params: any) => Promise<{ content: Array<{ type: string; text: string }> }>;
26
+ }, opts?: { optional: boolean }): void;
27
+ config?: Record<string, unknown>;
28
+ }
29
+
30
+ export type GetClientFn = () => Promise<FastmailMcpClient>;
31
+
32
+ /**
33
+ * Create a lazy client factory that connects on first tool call.
34
+ * One persistent connection per plugin instance (per workspace).
35
+ */
36
+ function lazyClientFactory(pluginConfig: {
37
+ workerUrl?: string;
38
+ bearerToken?: string;
39
+ }): GetClientFn {
40
+ let client: FastmailMcpClient | null = null;
41
+
42
+ return async () => {
43
+ if (client) return client;
44
+ const { url, token } = resolveCredentials(pluginConfig);
45
+ client = new FastmailMcpClient(url, token);
46
+ return client;
47
+ };
48
+ }
49
+
50
+ export default function register(api: OpenClawApi) {
51
+ const pluginConfig = (api.config || {}) as { workerUrl?: string; bearerToken?: string };
52
+ const getClient = lazyClientFactory(pluginConfig);
53
+
54
+ registerEmailTools(api, getClient);
55
+ registerContactTools(api, getClient);
56
+ registerCalendarTools(api, getClient);
57
+ registerMemoTools(api, getClient);
58
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "id": "fastmail-cli",
3
+ "configSchema": {
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "required": ["workerUrl", "bearerToken"],
7
+ "properties": {
8
+ "workerUrl": {
9
+ "type": "string",
10
+ "description": "Fastmail MCP Worker URL (e.g. https://fastmail-mcp.example.com)"
11
+ },
12
+ "bearerToken": {
13
+ "type": "string",
14
+ "description": "Bearer token from 'fastmail auth'. Each user needs their own token."
15
+ }
16
+ }
17
+ },
18
+ "uiHints": {
19
+ "workerUrl": {
20
+ "label": "Worker URL",
21
+ "placeholder": "https://fastmail-mcp.example.com"
22
+ },
23
+ "bearerToken": {
24
+ "label": "Bearer Token",
25
+ "placeholder": "Token from 'fastmail auth'"
26
+ }
27
+ },
28
+ "skills": [
29
+ "./skills"
30
+ ]
31
+ }
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "fastmail-cli",
3
+ "version": "1.0.0",
4
+ "description": "OpenClaw plugin for Fastmail email, contacts, and calendar",
5
+ "type": "module",
6
+ "files": [
7
+ "index.ts",
8
+ "src",
9
+ "skills",
10
+ "openclaw.plugin.json",
11
+ "README.md"
12
+ ],
13
+ "keywords": [
14
+ "openclaw",
15
+ "fastmail",
16
+ "email",
17
+ "mcp",
18
+ "agent-tools"
19
+ ],
20
+ "license": "MIT",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/omarshahine/fastmail-mcp-remote.git",
24
+ "directory": "openclaw-plugin"
25
+ },
26
+ "dependencies": {
27
+ "@modelcontextprotocol/sdk": "^1.26.0"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^25.0.8",
31
+ "typescript": "^5.9.0"
32
+ },
33
+ "openclaw": {
34
+ "extensions": [
35
+ "./index.ts"
36
+ ]
37
+ }
38
+ }
@@ -0,0 +1,136 @@
1
+ # Fastmail Tools
2
+
3
+ Token-efficient tools for Fastmail email, contacts, and calendar. Each tool connects to a remote Fastmail MCP Worker and returns compact text optimized for LLM token efficiency (5-7x savings vs raw JSON).
4
+
5
+ ## Authentication
6
+
7
+ Tools require `workerUrl` and `bearerToken` to be configured in the OpenClaw workspace. Each user needs their own token from `fastmail auth`.
8
+
9
+ ## Available Tools
10
+
11
+ ### Email Reading (11 tools)
12
+
13
+ | Tool | Purpose |
14
+ |------|---------|
15
+ | `fastmail_inbox` | Get recent inbox emails (IDs, dates, senders, subjects, previews) |
16
+ | `fastmail_get_email` | Read a single email (headers + body in markdown or HTML) |
17
+ | `fastmail_search_emails` | Search emails by text, with optional filters: sender, recipient, date range, unread, attachments, mailbox |
18
+ | `fastmail_get_thread` | Get all emails in a conversation thread |
19
+ | `fastmail_list_mailboxes` | List all mailboxes with IDs and email counts |
20
+ | `fastmail_get_mailbox_stats` | Get mailbox statistics (total, unread, threads) |
21
+ | `fastmail_get_account_summary` | Account overview with counts |
22
+ | `fastmail_list_identities` | List sending identities |
23
+ | `fastmail_get_attachments` | List attachments for an email |
24
+ | `fastmail_download_attachment` | Get download URL for an attachment |
25
+ | `fastmail_get_inbox_updates` | Incremental sync: get changes since a state token |
26
+
27
+ ### Email Writing (3 optional tools)
28
+
29
+ | Tool | Purpose |
30
+ |------|---------|
31
+ | `fastmail_send_email` | Send an email (text, HTML, or markdown body) |
32
+ | `fastmail_create_draft` | Create an email draft |
33
+ | `fastmail_reply_to_email` | Reply to an email (reply-all, send or draft) |
34
+
35
+ ### Email Organization (6 optional tools)
36
+
37
+ | Tool | Purpose |
38
+ |------|---------|
39
+ | `fastmail_mark_read` | Mark email as read |
40
+ | `fastmail_mark_unread` | Mark email as unread |
41
+ | `fastmail_flag` | Flag (star) an email |
42
+ | `fastmail_unflag` | Unflag (unstar) an email |
43
+ | `fastmail_delete` | Delete an email (move to trash) |
44
+ | `fastmail_move` | Move email to a different mailbox |
45
+
46
+ ### Bulk Operations (6 optional tools)
47
+
48
+ | Tool | Purpose |
49
+ |------|---------|
50
+ | `fastmail_bulk_read` | Mark multiple emails as read |
51
+ | `fastmail_bulk_unread` | Mark multiple emails as unread |
52
+ | `fastmail_bulk_flag` | Flag multiple emails |
53
+ | `fastmail_bulk_unflag` | Unflag multiple emails |
54
+ | `fastmail_bulk_delete` | Delete multiple emails |
55
+ | `fastmail_bulk_move` | Move multiple emails to a mailbox |
56
+
57
+ ### Contacts (3 tools)
58
+
59
+ | Tool | Purpose |
60
+ |------|---------|
61
+ | `fastmail_list_contacts` | List contacts with names, emails, phones |
62
+ | `fastmail_get_contact` | Full contact details |
63
+ | `fastmail_search_contacts` | Search contacts by name or email |
64
+
65
+ ### Calendar (4 tools)
66
+
67
+ | Tool | Purpose |
68
+ |------|---------|
69
+ | `fastmail_list_calendars` | List calendars with IDs |
70
+ | `fastmail_list_events` | List events, optionally by calendar |
71
+ | `fastmail_get_event` | Full event details |
72
+ | `fastmail_create_event` | Create a calendar event (optional) |
73
+
74
+ ### Memos (3 tools)
75
+
76
+ | Tool | Purpose |
77
+ |------|---------|
78
+ | `fastmail_get_memo` | Get the private memo on an email |
79
+ | `fastmail_create_memo` | Add a private memo to an email (optional) |
80
+ | `fastmail_delete_memo` | Delete a memo (optional) |
81
+
82
+ ## Output Format
83
+
84
+ Tools return compact text optimized for LLM consumption. Email IDs appear first on each line for easy extraction.
85
+
86
+ ### Email List Example
87
+ ```
88
+ # inbox (10)
89
+
90
+ M1234abc 2026-02-19 10:30 *John Smith <john@example.com>
91
+ Re: Project Update -- Preview of the email content...
92
+
93
+ M5678def 2026-02-19 09:15 Jane Doe <jane@example.com> [att]
94
+ Contract Review -- Please review the attached...
95
+ ```
96
+
97
+ Indicators: `*` = unread, `!` = flagged, `[att]` = has attachments
98
+
99
+ ### Single Email Example
100
+ ```
101
+ From: John Smith <john@example.com>
102
+ To: me@example.com
103
+ Date: 2026-02-19 10:30
104
+ Subject: Re: Project Update
105
+ ID: M1234abc | Thread: T5678
106
+
107
+ [markdown body content]
108
+ ```
109
+
110
+ ## Common Workflows
111
+
112
+ ### Check inbox and read an email
113
+ 1. `fastmail_inbox` -- see list, note IDs
114
+ 2. `fastmail_get_email` with the ID -- read the email
115
+
116
+ ### Search, read, and reply
117
+ 1. `fastmail_search_emails` with query
118
+ 2. `fastmail_get_email` with the ID
119
+ 3. `fastmail_reply_to_email` with body and `send: true`
120
+
121
+ ### Triage inbox
122
+ 1. `fastmail_inbox` with limit 20
123
+ 2. `fastmail_bulk_read` for read emails
124
+ 3. `fastmail_delete` for unwanted emails
125
+ 4. `fastmail_move` to archive
126
+
127
+ ### Incremental sync
128
+ 1. `fastmail_get_inbox_updates` (no state token) -- returns current state + emails
129
+ 2. Save the `queryState` from the response
130
+ 3. `fastmail_get_inbox_updates` with `sinceQueryState` -- only changes since last check
131
+
132
+ ## Error Handling
133
+
134
+ - **"Missing workerUrl/bearerToken"** -- Configure both in your OpenClaw workspace plugin settings
135
+ - **"Token expired"** -- User needs to run `fastmail auth` and update the bearerToken in workspace config
136
+ - **Connection errors** -- Check if the MCP worker is running
package/src/auth.ts ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Authentication for the Fastmail OpenClaw plugin.
3
+ *
4
+ * Credentials (workerUrl + bearerToken) are provided via plugin config,
5
+ * enabling multi-user setups where each workspace has its own token.
6
+ */
7
+
8
+ export interface Credentials {
9
+ url: string;
10
+ token: string;
11
+ }
12
+
13
+ /**
14
+ * Resolve credentials from plugin config. Both fields are required.
15
+ */
16
+ export function resolveCredentials(pluginConfig: {
17
+ workerUrl?: string;
18
+ bearerToken?: string;
19
+ }): Credentials {
20
+ if (!pluginConfig.workerUrl) {
21
+ throw new Error("Missing workerUrl in plugin config");
22
+ }
23
+ if (!pluginConfig.bearerToken) {
24
+ throw new Error("Missing bearerToken in plugin config");
25
+ }
26
+ return { url: pluginConfig.workerUrl, token: pluginConfig.bearerToken };
27
+ }