@agenticmail/openclaw 0.3.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/LICENSE +35 -0
- package/README.md +356 -0
- package/REFERENCE.md +677 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +3194 -0
- package/openclaw.plugin.json +90 -0
- package/package.json +62 -0
- package/skill/SKILL.md +221 -0
- package/skill/references/api-reference.md +66 -0
- package/skill/references/configuration.md +73 -0
- package/skill/scripts/health-check.sh +26 -0
- package/skill/scripts/setup.sh +56 -0
package/REFERENCE.md
ADDED
|
@@ -0,0 +1,677 @@
|
|
|
1
|
+
# @agenticmail/openclaw — Technical Reference
|
|
2
|
+
|
|
3
|
+
Complete technical reference for the AgenticMail OpenClaw plugin. Covers every tool, the channel integration, sub-agent lifecycle, rate limiting, follow-up system, and all constants.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Exports
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
export default function activate(api: any): void
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Single default export. Called by OpenClaw when the plugin loads.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Plugin Manifest
|
|
18
|
+
|
|
19
|
+
**File:** `openclaw.plugin.json`
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"id": "agenticmail",
|
|
24
|
+
"displayName": "AgenticMail",
|
|
25
|
+
"version": "0.2.0",
|
|
26
|
+
"description": "Full email channel + tools for AI agents",
|
|
27
|
+
"channels": ["mail"],
|
|
28
|
+
"configSchema": {
|
|
29
|
+
"apiUrl": { "type": "string", "default": "http://127.0.0.1:3100" },
|
|
30
|
+
"apiKey": { "type": "string", "required": true },
|
|
31
|
+
"masterKey": { "type": "string" }
|
|
32
|
+
},
|
|
33
|
+
"requires": { "bins": ["docker"] }
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Configuration
|
|
40
|
+
|
|
41
|
+
### ToolContext
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
interface ToolContext {
|
|
45
|
+
config: {
|
|
46
|
+
apiUrl: string; // Default: 'http://127.0.0.1:3100'
|
|
47
|
+
apiKey: string; // Agent API key (required)
|
|
48
|
+
masterKey?: string; // Master admin key (optional)
|
|
49
|
+
};
|
|
50
|
+
ownerName?: string; // Resolved from OpenClaw agent config
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Config Resolution
|
|
55
|
+
|
|
56
|
+
1. `api?.getConfig?.()` or `{}`
|
|
57
|
+
2. `api?.pluginConfig` or step 1 result
|
|
58
|
+
3. Manifest defaults
|
|
59
|
+
|
|
60
|
+
### Owner Name Resolution
|
|
61
|
+
|
|
62
|
+
Extracted from OpenClaw agent config: `api?.config?.agents?.list` → `defaultAgent?.identity?.name` or first agent's name.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## API Request Function
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
async function apiRequest(
|
|
70
|
+
ctx: ToolContext,
|
|
71
|
+
method: string,
|
|
72
|
+
path: string,
|
|
73
|
+
body?: unknown,
|
|
74
|
+
useMasterKey = false,
|
|
75
|
+
timeoutMs = 30_000
|
|
76
|
+
): Promise<any>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
- Base URL: `${ctx.config.apiUrl}/api/agenticmail${path}`
|
|
80
|
+
- Auth: `Authorization: Bearer ${useMasterKey ? ctx.config.masterKey : ctx.config.apiKey}`
|
|
81
|
+
- Throws if required key not configured
|
|
82
|
+
- Timeout: `AbortSignal.timeout(timeoutMs)` — 30 seconds default
|
|
83
|
+
- Error: `AgenticMail API error {status}: {text}`
|
|
84
|
+
- Response: JSON if Content-Type includes `application/json`, else `null`
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Sub-Agent Identity System
|
|
89
|
+
|
|
90
|
+
### SubagentAccount
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
interface SubagentAccount {
|
|
94
|
+
id: string;
|
|
95
|
+
name: string;
|
|
96
|
+
email: string;
|
|
97
|
+
apiKey: string;
|
|
98
|
+
parentEmail: string; // Coordinator's email (for auto-CC)
|
|
99
|
+
createdAt: number; // ms since epoch
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### AgentIdentity Registry
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
interface AgentIdentity {
|
|
107
|
+
apiKey: string;
|
|
108
|
+
parentEmail: string;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
registerAgentIdentity(name: string, apiKey: string, parentEmail: string): void
|
|
112
|
+
unregisterAgentIdentity(name: string): void
|
|
113
|
+
setLastActivatedAgent(name: string): void
|
|
114
|
+
clearLastActivatedAgent(name: string): void
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Context Resolution (4-path hierarchy)
|
|
118
|
+
|
|
119
|
+
1. **Direct injection:** `params._agentApiKey` (from tool factory)
|
|
120
|
+
2. **Raw key:** `params._auth` (from prepend context)
|
|
121
|
+
3. **Agent name:** `params._account` → lookup in identity registry → fallback to API lookup via master key
|
|
122
|
+
4. **Auto-detect:** `lastActivatedAgent` (zero-cooperation fallback)
|
|
123
|
+
|
|
124
|
+
### Auto-CC
|
|
125
|
+
|
|
126
|
+
When a sub-agent sends an inter-agent email (`@localhost`), the parent coordinator is automatically added to CC. External emails skip auto-CC. Deduplication prevents adding the parent if already in To or CC.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Inter-Agent Rate Limiting
|
|
131
|
+
|
|
132
|
+
### Configuration
|
|
133
|
+
|
|
134
|
+
| Parameter | Value |
|
|
135
|
+
|-----------|-------|
|
|
136
|
+
| `WARN_THRESHOLD` | 3 unanswered messages |
|
|
137
|
+
| `BLOCK_THRESHOLD` | 5 unanswered messages |
|
|
138
|
+
| `WINDOW_MAX` | 10 messages per window |
|
|
139
|
+
| `WINDOW_MS` | 300,000ms (5 minutes) |
|
|
140
|
+
| `COOLDOWN_MS` | 120,000ms (2 minutes) |
|
|
141
|
+
| `TRACKER_GC_INTERVAL_MS` | 600,000ms (10 minutes) |
|
|
142
|
+
| `TRACKER_STALE_MS` | 1,800,000ms (30 minutes) |
|
|
143
|
+
|
|
144
|
+
### MessageRecord
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
interface MessageRecord {
|
|
148
|
+
unanswered: number; // Consecutive unanswered count
|
|
149
|
+
sentTimestamps: number[]; // Timestamps within window
|
|
150
|
+
lastSentAt: number;
|
|
151
|
+
lastReplyAt: number;
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Functions
|
|
156
|
+
|
|
157
|
+
| Function | Description |
|
|
158
|
+
|----------|-------------|
|
|
159
|
+
| `checkRateLimit(from, to)` | Returns `{allowed, warning?}` |
|
|
160
|
+
| `recordSentMessage(from, to)` | Increments unanswered, adds timestamp |
|
|
161
|
+
| `recordInboundAgentMessage(from, to)` | Resets unanswered count |
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Outbound Security Guard
|
|
166
|
+
|
|
167
|
+
### Scan Function
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
function scanOutbound(
|
|
171
|
+
to: string | string[],
|
|
172
|
+
subject?: string,
|
|
173
|
+
text?: string,
|
|
174
|
+
html?: string,
|
|
175
|
+
attachments?: Array<{ filename?: string }>
|
|
176
|
+
): OutboundScanResultInline
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Returns: `{ warnings: McpOutboundWarning[], blocked: boolean, summary: string }`
|
|
180
|
+
|
|
181
|
+
Skips scanning if all recipients are `@localhost`.
|
|
182
|
+
|
|
183
|
+
### Detection Rules (38+)
|
|
184
|
+
|
|
185
|
+
**PII (13 rules):**
|
|
186
|
+
|
|
187
|
+
| Rule ID | Severity | Description |
|
|
188
|
+
|---------|----------|-------------|
|
|
189
|
+
| `ob_ssn` | HIGH | SSN pattern `\d{3}-\d{2}-\d{4}` |
|
|
190
|
+
| `ob_ssn_obfuscated` | HIGH | Obfuscated SSN variants |
|
|
191
|
+
| `ob_credit_card` | HIGH | Credit card numbers |
|
|
192
|
+
| `ob_phone` | MEDIUM | Phone number patterns |
|
|
193
|
+
| `ob_bank_routing` | HIGH | Routing/account numbers |
|
|
194
|
+
| `ob_drivers_license` | HIGH | Driver's license patterns |
|
|
195
|
+
| `ob_dob` | MEDIUM | Date of birth with keywords |
|
|
196
|
+
| `ob_passport` | HIGH | Passport numbers |
|
|
197
|
+
| `ob_tax_id` | HIGH | EIN/TIN patterns |
|
|
198
|
+
| `ob_itin` | HIGH | ITIN patterns |
|
|
199
|
+
| `ob_medicare` | HIGH | Medicare/Medicaid IDs |
|
|
200
|
+
| `ob_immigration` | HIGH | Immigration A-numbers |
|
|
201
|
+
| `ob_pin` | MEDIUM | PIN codes |
|
|
202
|
+
|
|
203
|
+
**Financial (5 rules):**
|
|
204
|
+
|
|
205
|
+
| Rule ID | Severity | Description |
|
|
206
|
+
|---------|----------|-------------|
|
|
207
|
+
| `ob_security_qa` | MEDIUM | Security Q&A patterns |
|
|
208
|
+
| `ob_iban` | HIGH | IBAN patterns |
|
|
209
|
+
| `ob_swift` | MEDIUM | SWIFT/BIC codes |
|
|
210
|
+
| `ob_crypto_wallet` | HIGH | BTC/ETH/XMR wallet addresses |
|
|
211
|
+
| `ob_wire_transfer` | HIGH | Wire transfer instructions |
|
|
212
|
+
|
|
213
|
+
**Credentials (16 rules):**
|
|
214
|
+
|
|
215
|
+
| Rule ID | Severity | Description |
|
|
216
|
+
|---------|----------|-------------|
|
|
217
|
+
| `ob_api_key` | HIGH | API key patterns |
|
|
218
|
+
| `ob_aws_key` | HIGH | `AKIA[A-Z0-9]{16}` |
|
|
219
|
+
| `ob_password_value` | HIGH | Password field patterns |
|
|
220
|
+
| `ob_private_key` | HIGH | PEM private key headers |
|
|
221
|
+
| `ob_bearer_token` | HIGH | Bearer token patterns |
|
|
222
|
+
| `ob_connection_string` | HIGH | DB connection strings |
|
|
223
|
+
| `ob_github_token` | HIGH | GitHub token patterns |
|
|
224
|
+
| `ob_stripe_key` | HIGH | Stripe key patterns |
|
|
225
|
+
| `ob_jwt` | HIGH | JWT token patterns |
|
|
226
|
+
| `ob_webhook_url` | HIGH | Slack/Discord webhook URLs |
|
|
227
|
+
| `ob_env_block` | HIGH | Consecutive ENV variable lines |
|
|
228
|
+
| `ob_seed_phrase` | HIGH | Crypto seed/recovery phrases |
|
|
229
|
+
| `ob_2fa_codes` | HIGH | 2FA backup codes |
|
|
230
|
+
| `ob_credential_pair` | HIGH | Username+password pairs |
|
|
231
|
+
| `ob_oauth_token` | HIGH | OAuth tokens |
|
|
232
|
+
| `ob_vpn_creds` | HIGH | VPN credentials |
|
|
233
|
+
|
|
234
|
+
**System Internals (3 rules):**
|
|
235
|
+
|
|
236
|
+
| Rule ID | Severity | Description |
|
|
237
|
+
|---------|----------|-------------|
|
|
238
|
+
| `ob_private_ip` | MEDIUM | Private IP ranges |
|
|
239
|
+
| `ob_file_path` | MEDIUM | File paths (/home, /Users, C:\\) |
|
|
240
|
+
| `ob_env_variable` | MEDIUM | Environment variable assignments |
|
|
241
|
+
|
|
242
|
+
**Owner Privacy (2 rules):**
|
|
243
|
+
|
|
244
|
+
| Rule ID | Severity | Description |
|
|
245
|
+
|---------|----------|-------------|
|
|
246
|
+
| `ob_owner_info` | HIGH | Owner's personal info |
|
|
247
|
+
| `ob_personal_reveal` | HIGH | Agent's creator/operator |
|
|
248
|
+
|
|
249
|
+
**Attachment Risk:**
|
|
250
|
+
|
|
251
|
+
| Risk Level | Extensions |
|
|
252
|
+
|------------|------------|
|
|
253
|
+
| HIGH (keys) | `.pem`, `.key`, `.p12`, `.pfx`, `.env`, `.credentials`, `.keystore`, `.jks`, `.p8` |
|
|
254
|
+
| MEDIUM (data) | `.db`, `.sqlite`, `.sqlite3`, `.sql`, `.csv`, `.tsv`, `.json`, `.yml`, `.yaml`, `.conf`, `.config`, `.ini` |
|
|
255
|
+
| HIGH (exec) | `.exe`, `.bat`, `.cmd`, `.ps1`, `.sh`, `.msi`, `.scr`, `.com`, `.vbs`, `.js`, `.wsf`, `.hta`, `.cpl`, `.jar`, `.app`, `.dmg`, `.run` |
|
|
256
|
+
| MEDIUM (archive) | `.zip`, `.rar`, `.7z`, `.tar`, `.gz`, `.bz2`, `.xz`, `.cab`, `.iso` |
|
|
257
|
+
| CRITICAL | Double extensions (e.g., `.pdf.exe`) |
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Tool Definitions (54 tools)
|
|
262
|
+
|
|
263
|
+
### Tool Registration
|
|
264
|
+
|
|
265
|
+
Tools are registered as factories — OpenClaw calls the factory per-session with `{sessionKey, ...}`. The sub-agent API key is injected at execution time through the 4-path context resolution hierarchy.
|
|
266
|
+
|
|
267
|
+
### Response Format
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
{
|
|
271
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
272
|
+
details: result
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### agenticmail_send
|
|
277
|
+
|
|
278
|
+
| Field | Type | Required | Description |
|
|
279
|
+
|-------|------|----------|-------------|
|
|
280
|
+
| `to` | string | Yes | Recipient |
|
|
281
|
+
| `subject` | string | Yes | Subject line |
|
|
282
|
+
| `text` | string | No | Plain text body |
|
|
283
|
+
| `html` | string | No | HTML body |
|
|
284
|
+
| `cc` | string | No | CC recipients |
|
|
285
|
+
| `inReplyTo` | string | No | Message-ID for threading |
|
|
286
|
+
| `references` | array | No | Message-ID chain |
|
|
287
|
+
| `attachments` | array | No | `{filename, content, contentType, encoding}` |
|
|
288
|
+
|
|
289
|
+
Auto-CC: Parent coordinator added to CC for inter-agent emails.
|
|
290
|
+
Outbound guard: Runs inline scan. If blocked, schedules follow-up reminders.
|
|
291
|
+
|
|
292
|
+
### agenticmail_inbox
|
|
293
|
+
|
|
294
|
+
| Field | Type | Default | Range |
|
|
295
|
+
|-------|------|---------|-------|
|
|
296
|
+
| `limit` | number | 20 | 1–100 |
|
|
297
|
+
| `offset` | number | 0 | 0+ |
|
|
298
|
+
|
|
299
|
+
### agenticmail_read
|
|
300
|
+
|
|
301
|
+
| Field | Type | Required | Default |
|
|
302
|
+
|-------|------|----------|---------|
|
|
303
|
+
| `uid` | number | Yes | — |
|
|
304
|
+
| `folder` | string | No | INBOX |
|
|
305
|
+
|
|
306
|
+
Response includes `_securityWarnings` and `_securityAdvisory` for external emails.
|
|
307
|
+
|
|
308
|
+
### agenticmail_search
|
|
309
|
+
|
|
310
|
+
| Field | Type | Description |
|
|
311
|
+
|-------|------|-------------|
|
|
312
|
+
| `from` | string | Sender filter |
|
|
313
|
+
| `to` | string | Recipient filter |
|
|
314
|
+
| `subject` | string | Subject filter |
|
|
315
|
+
| `text` | string | Body text search |
|
|
316
|
+
| `since` | string | ISO 8601 (after) |
|
|
317
|
+
| `before` | string | ISO 8601 (before) |
|
|
318
|
+
| `seen` | boolean | Read status |
|
|
319
|
+
| `searchRelay` | boolean | Also search Gmail/Outlook |
|
|
320
|
+
|
|
321
|
+
### agenticmail_import_relay
|
|
322
|
+
|
|
323
|
+
| Field | Type | Required |
|
|
324
|
+
|-------|------|----------|
|
|
325
|
+
| `uid` | number | Yes |
|
|
326
|
+
|
|
327
|
+
### agenticmail_delete
|
|
328
|
+
|
|
329
|
+
| Field | Type | Required |
|
|
330
|
+
|-------|------|----------|
|
|
331
|
+
| `uid` | number | Yes |
|
|
332
|
+
|
|
333
|
+
### agenticmail_reply
|
|
334
|
+
|
|
335
|
+
| Field | Type | Required | Default |
|
|
336
|
+
|-------|------|----------|---------|
|
|
337
|
+
| `uid` | number | Yes | — |
|
|
338
|
+
| `text` | string | Yes | — |
|
|
339
|
+
| `replyAll` | boolean | No | false |
|
|
340
|
+
|
|
341
|
+
Auto-quotes original, preserves In-Reply-To and References. Resets rate limiter on reply.
|
|
342
|
+
|
|
343
|
+
### agenticmail_forward
|
|
344
|
+
|
|
345
|
+
| Field | Type | Required |
|
|
346
|
+
|-------|------|----------|
|
|
347
|
+
| `uid` | number | Yes |
|
|
348
|
+
| `to` | string | Yes |
|
|
349
|
+
| `text` | string | No |
|
|
350
|
+
|
|
351
|
+
Preserves original attachments.
|
|
352
|
+
|
|
353
|
+
### Batch Operations
|
|
354
|
+
|
|
355
|
+
All require `uids: number[]` (non-empty array).
|
|
356
|
+
|
|
357
|
+
| Tool | Extra Fields | API Endpoint |
|
|
358
|
+
|------|-------------|-------------|
|
|
359
|
+
| `agenticmail_batch_read` | `folder?` | `POST /mail/batch/read` |
|
|
360
|
+
| `agenticmail_batch_delete` | `folder?` | `POST /mail/batch/delete` |
|
|
361
|
+
| `agenticmail_batch_mark_read` | `folder?` | `POST /mail/batch/seen` |
|
|
362
|
+
| `agenticmail_batch_mark_unread` | `folder?` | `POST /mail/batch/unseen` |
|
|
363
|
+
| `agenticmail_batch_move` | `from?`, `to` (required) | `POST /mail/batch/move` |
|
|
364
|
+
|
|
365
|
+
### agenticmail_digest
|
|
366
|
+
|
|
367
|
+
| Field | Type | Default | Range |
|
|
368
|
+
|-------|------|---------|-------|
|
|
369
|
+
| `limit` | number | 20 | 1–50 |
|
|
370
|
+
| `offset` | number | 0 | 0+ |
|
|
371
|
+
| `folder` | string | INBOX | — |
|
|
372
|
+
| `previewLength` | number | 200 | 1–500 |
|
|
373
|
+
|
|
374
|
+
### agenticmail_template_send
|
|
375
|
+
|
|
376
|
+
| Field | Type | Required |
|
|
377
|
+
|-------|------|----------|
|
|
378
|
+
| `id` | string | Yes |
|
|
379
|
+
| `to` | string | Yes |
|
|
380
|
+
| `variables` | object | No |
|
|
381
|
+
| `cc` | string | No |
|
|
382
|
+
| `bcc` | string | No |
|
|
383
|
+
|
|
384
|
+
### Folder Management
|
|
385
|
+
|
|
386
|
+
| Tool | Fields | API |
|
|
387
|
+
|------|--------|-----|
|
|
388
|
+
| `agenticmail_folders` | (none) | `GET /mail/folders` |
|
|
389
|
+
| `agenticmail_list_folder` | `folder`, `limit?`, `offset?` | `GET /mail/folders/{folder}` |
|
|
390
|
+
| `agenticmail_create_folder` | `name` | `POST /mail/folders` |
|
|
391
|
+
| `agenticmail_move` | `uid`, `to`, `from?` | `POST /mail/messages/{uid}/move` |
|
|
392
|
+
| `agenticmail_mark_read` | `uid` | `POST /mail/messages/{uid}/seen` |
|
|
393
|
+
| `agenticmail_mark_unread` | `uid` | `POST /mail/messages/{uid}/unseen` |
|
|
394
|
+
|
|
395
|
+
### Organization Tools
|
|
396
|
+
|
|
397
|
+
All action-based tools use `{ action: string, ... }` pattern.
|
|
398
|
+
|
|
399
|
+
**agenticmail_contacts:** Actions: `list`, `add` (email required, name optional), `delete` (id)
|
|
400
|
+
|
|
401
|
+
**agenticmail_tags:** Actions: `list`, `create` (name, color?), `delete` (id), `tag_message` (id, uid, folder?), `untag_message` (id, uid, folder?), `get_messages` (id), `get_message_tags` (uid)
|
|
402
|
+
|
|
403
|
+
**agenticmail_drafts:** Actions: `list`, `create` (to, subject, text), `update` (id, fields), `delete` (id), `send` (id)
|
|
404
|
+
|
|
405
|
+
**agenticmail_signatures:** Actions: `list`, `create` (name, text, isDefault?), `delete` (id)
|
|
406
|
+
|
|
407
|
+
**agenticmail_templates:** Actions: `list`, `create` (name, subject, text), `delete` (id)
|
|
408
|
+
|
|
409
|
+
**agenticmail_schedule:** Actions: `create` (to, subject, text, sendAt), `list`, `cancel` (id)
|
|
410
|
+
|
|
411
|
+
**agenticmail_rules:** Actions: `list`, `create` (name, conditions, actions, priority?), `delete` (id)
|
|
412
|
+
- Conditions: `from_contains`, `from_exact`, `subject_contains`, `subject_regex`, `to_contains`, `has_attachment`
|
|
413
|
+
- Actions: `move_to`, `mark_read`, `delete`, `add_tags`
|
|
414
|
+
|
|
415
|
+
### Security Tools
|
|
416
|
+
|
|
417
|
+
**agenticmail_spam:** Actions: `list` (limit?, offset?), `report` (uid, folder?), `not_spam` (uid), `score` (uid, folder?)
|
|
418
|
+
|
|
419
|
+
**agenticmail_pending_emails:** Actions: `list`, `get` (id)
|
|
420
|
+
- `approve` and `reject` are **explicitly blocked** — returns error directing agent to notify owner
|
|
421
|
+
|
|
422
|
+
**agenticmail_cleanup** (master key): Actions: `list_inactive` (hours?), `cleanup` (hours?, dryRun?), `set_persistent` (agentId, persistent)
|
|
423
|
+
|
|
424
|
+
### Inter-Agent Communication
|
|
425
|
+
|
|
426
|
+
**agenticmail_list_agents:** Returns `{agents: [{name, email, role}]}`. Falls back to master key list.
|
|
427
|
+
|
|
428
|
+
**agenticmail_message_agent:**
|
|
429
|
+
| Field | Type | Required |
|
|
430
|
+
|-------|------|----------|
|
|
431
|
+
| `agent` | string | Yes |
|
|
432
|
+
| `subject` | string | Yes |
|
|
433
|
+
| `text` | string | Yes |
|
|
434
|
+
| `priority` | "normal"\|"high"\|"urgent" | No |
|
|
435
|
+
|
|
436
|
+
Validates agent exists. Prevents self-messaging. Rate-limited. Priority prefixes subject with `[URGENT]` or `[HIGH]`.
|
|
437
|
+
|
|
438
|
+
**agenticmail_check_messages:** Fetches up to 10 unread messages. Tags as `[agent]` or `[external]`. Resets rate limiter.
|
|
439
|
+
|
|
440
|
+
**agenticmail_wait_for_email:**
|
|
441
|
+
| Field | Type | Default | Range |
|
|
442
|
+
|-------|------|---------|-------|
|
|
443
|
+
| `timeout` | number | 120 | 5–300 |
|
|
444
|
+
|
|
445
|
+
Uses SSE push with polling fallback. Returns email or task events.
|
|
446
|
+
|
|
447
|
+
### Task Queue
|
|
448
|
+
|
|
449
|
+
**agenticmail_assign_task:** `{assignee, taskType?, payload?, expiresInSeconds?}`
|
|
450
|
+
|
|
451
|
+
**agenticmail_check_tasks:** `{direction: "incoming"|"outgoing", assignee?}`
|
|
452
|
+
|
|
453
|
+
**agenticmail_claim_task:** `{id}`
|
|
454
|
+
|
|
455
|
+
**agenticmail_submit_result:** `{id, result?}`
|
|
456
|
+
|
|
457
|
+
**agenticmail_call_agent:** `{target, task, payload?, timeout?}` — synchronous RPC, polls every 2s
|
|
458
|
+
|
|
459
|
+
### Account Management
|
|
460
|
+
|
|
461
|
+
**agenticmail_whoami:** `GET /accounts/me`
|
|
462
|
+
|
|
463
|
+
**agenticmail_update_metadata:** `{metadata: object}` → `PATCH /accounts/me`
|
|
464
|
+
|
|
465
|
+
**agenticmail_create_account** (master): `{name, domain?, role?}` — also registers in identity registry
|
|
466
|
+
|
|
467
|
+
**agenticmail_delete_agent** (master): `{name, reason?}` → archives emails, generates deletion report
|
|
468
|
+
|
|
469
|
+
**agenticmail_deletion_reports** (master): `{id?}` — list all or get specific
|
|
470
|
+
|
|
471
|
+
### Gateway Tools (all master key)
|
|
472
|
+
|
|
473
|
+
**agenticmail_status:** `GET /health`
|
|
474
|
+
|
|
475
|
+
**agenticmail_setup_guide:** Returns relay vs domain comparison
|
|
476
|
+
|
|
477
|
+
**agenticmail_setup_relay:** `{provider, email, password, smtpHost?, smtpPort?, imapHost?, imapPort?, agentName?, agentRole?, skipDefaultAgent?}`
|
|
478
|
+
|
|
479
|
+
**agenticmail_setup_domain:** `{cloudflareToken, cloudflareAccountId, domain?, purchase?, gmailRelay?}`
|
|
480
|
+
|
|
481
|
+
**agenticmail_setup_gmail_alias:** `{agentEmail, agentDisplayName?}`
|
|
482
|
+
|
|
483
|
+
**agenticmail_setup_payment:** No input
|
|
484
|
+
|
|
485
|
+
**agenticmail_purchase_domain:** `{keywords: string[], tld?}`
|
|
486
|
+
|
|
487
|
+
**agenticmail_gateway_status:** `GET /gateway/status`
|
|
488
|
+
|
|
489
|
+
**agenticmail_test_email:** `{to}` → `POST /gateway/test`
|
|
490
|
+
|
|
491
|
+
---
|
|
492
|
+
|
|
493
|
+
## Email Channel Integration
|
|
494
|
+
|
|
495
|
+
### Channel Metadata
|
|
496
|
+
|
|
497
|
+
```typescript
|
|
498
|
+
{
|
|
499
|
+
id: 'mail',
|
|
500
|
+
label: 'Email',
|
|
501
|
+
selectionLabel: 'Email (AgenticMail)',
|
|
502
|
+
capabilities: {
|
|
503
|
+
chatTypes: ['direct'],
|
|
504
|
+
media: true,
|
|
505
|
+
reply: true,
|
|
506
|
+
threads: true
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
### ResolvedMailAccount
|
|
512
|
+
|
|
513
|
+
```typescript
|
|
514
|
+
{
|
|
515
|
+
accountId: string;
|
|
516
|
+
apiUrl: string;
|
|
517
|
+
apiKey: string;
|
|
518
|
+
watchMailboxes: string[]; // Default: ['INBOX']
|
|
519
|
+
pollIntervalMs: number; // Default: 30,000
|
|
520
|
+
enabled: boolean;
|
|
521
|
+
}
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### Monitoring
|
|
525
|
+
|
|
526
|
+
1. **SSE push** — connects to `GET /events` for IMAP IDLE-backed notifications
|
|
527
|
+
2. **Polling fallback** — exponential backoff: 2s → 4s → 8s → 16s → 30s max
|
|
528
|
+
3. **Processed UID tracking** — caps at 1000 (keeps latest 500)
|
|
529
|
+
|
|
530
|
+
### Email Dispatch Pipeline
|
|
531
|
+
|
|
532
|
+
1. New email detected (via SSE or poll)
|
|
533
|
+
2. Build message context (OpenClaw format)
|
|
534
|
+
3. Extract thread ID from `References[0]` or `messageId`
|
|
535
|
+
4. Dispatch through `runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher`
|
|
536
|
+
5. Mark email as read
|
|
537
|
+
|
|
538
|
+
---
|
|
539
|
+
|
|
540
|
+
## Follow-Up System
|
|
541
|
+
|
|
542
|
+
### FollowUpEntry
|
|
543
|
+
|
|
544
|
+
```typescript
|
|
545
|
+
interface FollowUpEntry {
|
|
546
|
+
pendingId: string;
|
|
547
|
+
recipient: string;
|
|
548
|
+
subject: string;
|
|
549
|
+
step: number; // 0-indexed within cycle
|
|
550
|
+
cycle: number; // Full cycles completed
|
|
551
|
+
nextFireAt: string; // ISO timestamp
|
|
552
|
+
createdAt: string; // ISO timestamp
|
|
553
|
+
sessionKey: string; // OpenClaw session key
|
|
554
|
+
apiUrl: string;
|
|
555
|
+
apiKey: string;
|
|
556
|
+
}
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
### Schedule
|
|
560
|
+
|
|
561
|
+
| Step | Delay |
|
|
562
|
+
|------|-------|
|
|
563
|
+
| 0 | 12 hours |
|
|
564
|
+
| 1 | 6 hours |
|
|
565
|
+
| 2 | 3 hours |
|
|
566
|
+
| 3 | 1 hour (final) |
|
|
567
|
+
| — | 3-day cooldown |
|
|
568
|
+
| 4+ | Cycle restarts |
|
|
569
|
+
|
|
570
|
+
### Persistence
|
|
571
|
+
|
|
572
|
+
Stored at `${stateDir}/agenticmail-followups.json`:
|
|
573
|
+
```json
|
|
574
|
+
{ "version": 1, "entries": [...] }
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
Restored on startup. Entries >1 day overdue are skipped.
|
|
578
|
+
|
|
579
|
+
### Delivery
|
|
580
|
+
|
|
581
|
+
Reminders delivered via `api.runtime.system.enqueueSystemEvent()`.
|
|
582
|
+
|
|
583
|
+
### API
|
|
584
|
+
|
|
585
|
+
| Function | Description |
|
|
586
|
+
|----------|-------------|
|
|
587
|
+
| `initFollowUpSystem(api)` | Initialize (restore persisted state) |
|
|
588
|
+
| `scheduleFollowUp(pendingId, recipient, subject, sessionKey, apiUrl, apiKey)` | Start tracking |
|
|
589
|
+
| `cancelFollowUp(pendingId)` | Cancel specific |
|
|
590
|
+
| `cancelAllFollowUps()` | Cancel all |
|
|
591
|
+
| `activeFollowUpCount()` | Count tracked |
|
|
592
|
+
| `getFollowUpSummary()` | Get all entries summary |
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
## Lifecycle Hooks
|
|
597
|
+
|
|
598
|
+
### before_agent_start
|
|
599
|
+
|
|
600
|
+
1. Detect sub-agent session (`sessionKey.includes(':subagent:')`)
|
|
601
|
+
2. Provision email account via `POST /accounts`
|
|
602
|
+
3. Handle 409 conflict with UUID-suffixed retry
|
|
603
|
+
4. Send auto-intro email in coordination thread
|
|
604
|
+
5. Inject context: identity, mailbox requirement, security rules, unread mail summary
|
|
605
|
+
|
|
606
|
+
### before_tool_call
|
|
607
|
+
|
|
608
|
+
1. Inject sub-agent API key for `agenticmail_*` tools
|
|
609
|
+
2. Inject pending email notifications from SSE watchers
|
|
610
|
+
3. Capture `sessions_spawn` info (enforce min 10-minute timeout)
|
|
611
|
+
|
|
612
|
+
### agent_end
|
|
613
|
+
|
|
614
|
+
1. Cancel all follow-ups
|
|
615
|
+
2. Remove from registries
|
|
616
|
+
3. Stop SSE watcher
|
|
617
|
+
4. Delay 5 seconds (grace period)
|
|
618
|
+
5. Delete account via `DELETE /accounts/{id}` with master key
|
|
619
|
+
|
|
620
|
+
---
|
|
621
|
+
|
|
622
|
+
## Health Monitor Service
|
|
623
|
+
|
|
624
|
+
```typescript
|
|
625
|
+
{
|
|
626
|
+
id: 'agenticmail-monitor',
|
|
627
|
+
start(): validates API connectivity, logs agent name and email
|
|
628
|
+
stop(): logs shutdown
|
|
629
|
+
}
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
---
|
|
633
|
+
|
|
634
|
+
## Constants Summary
|
|
635
|
+
|
|
636
|
+
| Constant | Value | Description |
|
|
637
|
+
|----------|-------|-------------|
|
|
638
|
+
| `MIN_SUBAGENT_TIMEOUT_S` | 600 (10 min) | Minimum sub-agent session timeout |
|
|
639
|
+
| `SUBAGENT_GC_INTERVAL_MS` | 900,000 (15 min) | Sub-agent garbage collection interval |
|
|
640
|
+
| `SUBAGENT_MAX_AGE_MS` | 7,200,000 (2 hr) | Max sub-agent account age |
|
|
641
|
+
| `CLEANUP_GRACE_MS` | 5,000 (5 sec) | Grace period before account deletion |
|
|
642
|
+
| `RATE_LIMIT.WARN_THRESHOLD` | 3 | Unanswered messages before warning |
|
|
643
|
+
| `RATE_LIMIT.BLOCK_THRESHOLD` | 5 | Unanswered messages before blocking |
|
|
644
|
+
| `RATE_LIMIT.WINDOW_MAX` | 10 | Max messages per window |
|
|
645
|
+
| `RATE_LIMIT.WINDOW_MS` | 300,000 (5 min) | Rate limit window |
|
|
646
|
+
| `RATE_LIMIT.COOLDOWN_MS` | 120,000 (2 min) | Cooldown after block |
|
|
647
|
+
| `TRACKER_GC_INTERVAL_MS` | 600,000 (10 min) | Rate limiter GC interval |
|
|
648
|
+
| `TRACKER_STALE_MS` | 1,800,000 (30 min) | Rate limiter stale threshold |
|
|
649
|
+
| `SSE_INITIAL_DELAY_MS` | 2,000 | Initial SSE reconnect backoff |
|
|
650
|
+
| `SSE_MAX_DELAY_MS` | 30,000 | Max SSE reconnect backoff |
|
|
651
|
+
| `apiRequest timeout` | 30,000 | Default API timeout |
|
|
652
|
+
| `HEARTBEAT_INTERVAL_MS` | 300,000 (5 min) | Pending email check interval |
|
|
653
|
+
| Follow-up cooldown | 259,200,000 (3 days) | Between follow-up cycles |
|
|
654
|
+
| Follow-up steps | [12h, 6h, 3h, 1h] | Escalating reminder delays |
|
|
655
|
+
| `processedUids` cap | 1,000 (keep 500) | Channel UID tracking limit |
|
|
656
|
+
| `pollIntervalMs` default | 30,000 | Channel polling interval |
|
|
657
|
+
|
|
658
|
+
---
|
|
659
|
+
|
|
660
|
+
## Skill Files
|
|
661
|
+
|
|
662
|
+
```
|
|
663
|
+
skill/
|
|
664
|
+
├── SKILL.md # Main skill definition (injected into prompt)
|
|
665
|
+
├── references/
|
|
666
|
+
│ ├── api-reference.md # API endpoint reference
|
|
667
|
+
│ └── configuration.md # Config guide
|
|
668
|
+
└── scripts/
|
|
669
|
+
├── health-check.sh # Server health check
|
|
670
|
+
└── setup.sh # Setup helper
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
---
|
|
674
|
+
|
|
675
|
+
## License
|
|
676
|
+
|
|
677
|
+
[MIT](./LICENSE) - Ope Olatunji ([@ope-olatunji](https://github.com/ope-olatunji))
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare function activate(api: any): void;
|
|
2
|
+
/**
|
|
3
|
+
* OpenClaw plugin module export.
|
|
4
|
+
* Must export an object with `id` and `register` — OpenClaw reads `id` for identification
|
|
5
|
+
* and calls `register(api)` during plugin activation.
|
|
6
|
+
*/
|
|
7
|
+
declare const _default: {
|
|
8
|
+
id: string;
|
|
9
|
+
register: typeof activate;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export { _default as default };
|