@agenticmail/mcp 0.7.4 → 0.7.7
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/dist/index.js +117 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -22395,6 +22395,12 @@ var TOOL_SETS = {
|
|
|
22395
22395
|
// back. Essential enough that paying its tokens at every spawn beats
|
|
22396
22396
|
// making the agent discover it via request_tools.
|
|
22397
22397
|
"wait_for_email",
|
|
22398
|
+
// check_activity is the dispatcher visibility primitive: see which
|
|
22399
|
+
// agents the dispatcher has woken right now (or in the last 2 min)
|
|
22400
|
+
// and how long they have been running. The host uses it to answer
|
|
22401
|
+
// "did the agent I just emailed actually start working?" without
|
|
22402
|
+
// having to wait for a reply or send an acknowledgment.
|
|
22403
|
+
"check_activity",
|
|
22398
22404
|
"check_tasks"
|
|
22399
22405
|
],
|
|
22400
22406
|
/** Less-common mail operations. */
|
|
@@ -22609,7 +22615,7 @@ async function apiRequest(method, path, body, useMasterKey = false, timeoutMs =
|
|
|
22609
22615
|
var toolDefinitions = [
|
|
22610
22616
|
{
|
|
22611
22617
|
name: "send_email",
|
|
22612
|
-
description: "Send an email from the agent's mailbox. Supports multiple recipients on To and CC (comma-separated). This is the PRIMARY primitive for multi-agent coordination: kick off a thread with all participants on CC, and every local recipient is woken automatically
|
|
22618
|
+
description: "Send an email from the agent's mailbox. Supports multiple recipients on To and CC (comma-separated). This is the PRIMARY primitive for multi-agent coordination: kick off a thread with all participants on CC, and every local recipient is woken automatically \u2014 UNLESS you set `wake` to limit the wake-up to specific agents. Use `wake` aggressively on large threads: 15 agents on CC \xD7 every reply burns 15 Claude turns per round if every recipient wakes. Naming the single next actor cuts that to one. External emails are scanned for sensitive content; HIGH severity detections are BLOCKED for owner approval. You CANNOT bypass the outbound guard.",
|
|
22613
22619
|
inputSchema: {
|
|
22614
22620
|
type: "object",
|
|
22615
22621
|
properties: {
|
|
@@ -22617,7 +22623,12 @@ var toolDefinitions = [
|
|
|
22617
22623
|
subject: { type: "string", description: "Email subject line" },
|
|
22618
22624
|
text: { type: "string", description: "Plain text body" },
|
|
22619
22625
|
html: { type: "string", description: "HTML body (optional)" },
|
|
22620
|
-
cc: { type: "string", description: 'CC recipients \u2014 the team. Comma-separated, e.g. "vesper@localhost, orion@localhost". Every local @localhost recipient is auto-woken when this email lands.' },
|
|
22626
|
+
cc: { type: "string", description: 'CC recipients \u2014 the team. Comma-separated, e.g. "vesper@localhost, orion@localhost". Every local @localhost recipient is auto-woken when this email lands UNLESS you also pass `wake` to restrict.' },
|
|
22627
|
+
wake: {
|
|
22628
|
+
type: "array",
|
|
22629
|
+
items: { type: "string" },
|
|
22630
|
+
description: 'Optional. Names (or @localhost addresses) of the agents the dispatcher should give a Claude turn to when this mail lands. CC\'d agents NOT in this list still receive the email but get no Claude turn \u2014 they will see it the next time someone explicitly wakes them or they check their inbox. Use this to scope cost on large threads: send to 15 agents but wake only the 1 or 2 who need to act next. Pass an empty array `[]` for "deliver silently \u2014 wake nobody". Omit entirely to keep the default "wake everyone CC\'d" behaviour.'
|
|
22631
|
+
},
|
|
22621
22632
|
inReplyTo: { type: "string", description: "Message-ID to reply to (optional)" },
|
|
22622
22633
|
references: {
|
|
22623
22634
|
type: "array",
|
|
@@ -22705,27 +22716,37 @@ var toolDefinitions = [
|
|
|
22705
22716
|
},
|
|
22706
22717
|
{
|
|
22707
22718
|
name: "reply_email",
|
|
22708
|
-
description: "Reply to an email. Fetches the original message, auto-fills To, Subject (Re:), In-Reply-To, and References, then sends with quoted body. **For multi-agent thread coordination, pass `replyAll: true`** so every CC'd participant sees your contribution and stays in context \u2014 that is how the thread-as-workspace pattern works. Outbound guard applies \u2014 HIGH severity content is held for review.",
|
|
22719
|
+
description: "Reply to an email. Fetches the original message, auto-fills To, Subject (Re:), In-Reply-To, and References, then sends with quoted body. **For multi-agent thread coordination, pass `replyAll: true`** so every CC'd participant sees your contribution and stays in context \u2014 that is how the thread-as-workspace pattern works. **Pass `wake` to name only the next actor(s)** so the dispatcher gives a Claude turn only to them; everyone else still receives the mail but stays asleep. Outbound guard applies \u2014 HIGH severity content is held for review.",
|
|
22709
22720
|
inputSchema: {
|
|
22710
22721
|
type: "object",
|
|
22711
22722
|
properties: {
|
|
22712
22723
|
uid: { type: "number", description: "UID of the email to reply to" },
|
|
22713
22724
|
text: { type: "string", description: "Your reply text" },
|
|
22714
22725
|
html: { type: "string", description: "HTML reply (optional)" },
|
|
22715
|
-
replyAll: { type: "boolean", description: "Reply to all recipients (default: false)" }
|
|
22726
|
+
replyAll: { type: "boolean", description: "Reply to all recipients (default: false)" },
|
|
22727
|
+
wake: {
|
|
22728
|
+
type: "array",
|
|
22729
|
+
items: { type: "string" },
|
|
22730
|
+
description: "Optional. Names of the agents who should get a Claude turn from the dispatcher when this reply lands. CC'd agents NOT in this list still receive the email but stay asleep \u2014 saves significant tokens on large threads. Pass `[]` to deliver silently. Omit to wake everyone CC'd."
|
|
22731
|
+
}
|
|
22716
22732
|
},
|
|
22717
22733
|
required: ["uid", "text"]
|
|
22718
22734
|
}
|
|
22719
22735
|
},
|
|
22720
22736
|
{
|
|
22721
22737
|
name: "forward_email",
|
|
22722
|
-
description: "Forward an email to another recipient. Outbound guard applies \u2014 HIGH severity content is held for review.",
|
|
22738
|
+
description: "Forward an email to another recipient. Outbound guard applies \u2014 HIGH severity content is held for review. Pass `wake` to limit which local recipients get a Claude turn from the dispatcher when this forward lands.",
|
|
22723
22739
|
inputSchema: {
|
|
22724
22740
|
type: "object",
|
|
22725
22741
|
properties: {
|
|
22726
22742
|
uid: { type: "number", description: "UID of the email to forward" },
|
|
22727
22743
|
to: { type: "string", description: "Recipient to forward to" },
|
|
22728
|
-
text: { type: "string", description: "Additional message (optional)" }
|
|
22744
|
+
text: { type: "string", description: "Additional message (optional)" },
|
|
22745
|
+
wake: {
|
|
22746
|
+
type: "array",
|
|
22747
|
+
items: { type: "string" },
|
|
22748
|
+
description: "Optional. Names of the agents who should get a Claude turn when the forward lands. Pass `[]` to deliver silently. Omit to wake everyone CC'd."
|
|
22749
|
+
}
|
|
22729
22750
|
},
|
|
22730
22751
|
required: ["uid", "to"]
|
|
22731
22752
|
}
|
|
@@ -22826,7 +22847,7 @@ var toolDefinitions = [
|
|
|
22826
22847
|
},
|
|
22827
22848
|
{
|
|
22828
22849
|
name: "manage_drafts",
|
|
22829
|
-
description: "List, create, update, send, or delete drafts",
|
|
22850
|
+
description: "List, create, update, send, or delete drafts. On send, you can pass `wake` to limit which local recipients get a Claude turn \u2014 same semantics as send_email.",
|
|
22830
22851
|
inputSchema: {
|
|
22831
22852
|
type: "object",
|
|
22832
22853
|
properties: {
|
|
@@ -22834,7 +22855,12 @@ var toolDefinitions = [
|
|
|
22834
22855
|
id: { type: "string", description: "Draft ID (for update/send/delete)" },
|
|
22835
22856
|
to: { type: "string", description: "Recipient (for create/update)" },
|
|
22836
22857
|
subject: { type: "string", description: "Subject (for create/update)" },
|
|
22837
|
-
text: { type: "string", description: "Body text (for create/update)" }
|
|
22858
|
+
text: { type: "string", description: "Body text (for create/update)" },
|
|
22859
|
+
wake: {
|
|
22860
|
+
type: "array",
|
|
22861
|
+
items: { type: "string" },
|
|
22862
|
+
description: "Optional, for action=send. Names of the agents who should get a Claude turn when the drafted mail lands. Pass `[]` to deliver silently. Omit to wake everyone CC'd."
|
|
22863
|
+
}
|
|
22838
22864
|
},
|
|
22839
22865
|
required: ["action"]
|
|
22840
22866
|
}
|
|
@@ -23191,7 +23217,12 @@ var toolDefinitions = [
|
|
|
23191
23217
|
to: { type: "string", description: "Recipient email" },
|
|
23192
23218
|
variables: { type: "object", description: 'Variables to substitute: { name: "Alice" }' },
|
|
23193
23219
|
cc: { type: "string", description: "CC recipients" },
|
|
23194
|
-
bcc: { type: "string", description: "BCC recipients" }
|
|
23220
|
+
bcc: { type: "string", description: "BCC recipients" },
|
|
23221
|
+
wake: {
|
|
23222
|
+
type: "array",
|
|
23223
|
+
items: { type: "string" },
|
|
23224
|
+
description: "Optional. Names of the agents who should get a Claude turn when this template-rendered mail lands. Pass `[]` to deliver silently. Omit to wake everyone CC'd."
|
|
23225
|
+
}
|
|
23195
23226
|
},
|
|
23196
23227
|
required: ["id", "to"]
|
|
23197
23228
|
}
|
|
@@ -23227,6 +23258,17 @@ var toolDefinitions = [
|
|
|
23227
23258
|
required: ["action"]
|
|
23228
23259
|
}
|
|
23229
23260
|
},
|
|
23261
|
+
{
|
|
23262
|
+
name: "check_activity",
|
|
23263
|
+
description: "Check which agents are currently being woken by the dispatcher (right now or in the last 2 minutes). Use this when you sent mail to a teammate and want to know if they have actually started working, or to audit the live multi-agent state. Returns active workers with the agent name, what triggered the wake (mail UID + subject, or task id), how long they have been running, and a preview of the most recent finished work. Requires master key \u2014 the host session has it; subagents normally do not.",
|
|
23264
|
+
inputSchema: {
|
|
23265
|
+
type: "object",
|
|
23266
|
+
properties: {
|
|
23267
|
+
agent: { type: "string", description: "Filter to a specific agent by name (case-insensitive). Omit to see every active and recently-finished worker." },
|
|
23268
|
+
includeRecent: { type: "boolean", description: "Include workers that finished in the last ~2 minutes (default: true). Set false to see only currently-running workers." }
|
|
23269
|
+
}
|
|
23270
|
+
}
|
|
23271
|
+
},
|
|
23230
23272
|
{
|
|
23231
23273
|
name: "check_tasks",
|
|
23232
23274
|
description: "Check for pending tasks assigned to you (or a specific agent) or tasks you assigned to others",
|
|
@@ -23568,6 +23610,9 @@ async function dispatchToolCall(name, args2, useMaster) {
|
|
|
23568
23610
|
...a.encoding ? { encoding: a.encoding } : {}
|
|
23569
23611
|
}));
|
|
23570
23612
|
}
|
|
23613
|
+
if (args2.wake !== void 0) {
|
|
23614
|
+
sendBody.wake = args2.wake;
|
|
23615
|
+
}
|
|
23571
23616
|
const result = await apiRequest("POST", "/mail/send", sendBody);
|
|
23572
23617
|
if (result?.blocked && result?.pendingId) {
|
|
23573
23618
|
scheduleFollowUp(result.pendingId, String(args2.to), String(args2.subject || "(no subject)"), makePendingCheck(result.pendingId));
|
|
@@ -23701,6 +23746,9 @@ ${quotedBody}`;
|
|
|
23701
23746
|
inReplyTo: original.messageId,
|
|
23702
23747
|
references: refs
|
|
23703
23748
|
};
|
|
23749
|
+
if (args2.wake !== void 0) {
|
|
23750
|
+
replySendBody.wake = args2.wake;
|
|
23751
|
+
}
|
|
23704
23752
|
const sendResult = await apiRequest("POST", "/mail/send", replySendBody);
|
|
23705
23753
|
if (sendResult?.blocked && sendResult?.pendingId) {
|
|
23706
23754
|
scheduleFollowUp(sendResult.pendingId, to, String(replySendBody.subject || "(no subject)"), makePendingCheck(sendResult.pendingId));
|
|
@@ -23749,6 +23797,9 @@ ${orig.text || ""}`;
|
|
|
23749
23797
|
encoding: "base64"
|
|
23750
23798
|
}));
|
|
23751
23799
|
}
|
|
23800
|
+
if (args2.wake !== void 0) {
|
|
23801
|
+
fwdSendBody.wake = args2.wake;
|
|
23802
|
+
}
|
|
23752
23803
|
const fwdResult = await apiRequest("POST", "/mail/send", fwdSendBody);
|
|
23753
23804
|
if (fwdResult?.blocked && fwdResult?.pendingId) {
|
|
23754
23805
|
scheduleFollowUp(fwdResult.pendingId, String(args2.to), fwdSubject, makePendingCheck(fwdResult.pendingId));
|
|
@@ -23853,7 +23904,9 @@ ${lines.join("\n")}`;
|
|
|
23853
23904
|
}
|
|
23854
23905
|
if (args2.action === "send") {
|
|
23855
23906
|
if (!args2.id) throw new Error("id is required");
|
|
23856
|
-
const
|
|
23907
|
+
const draftSendBody = {};
|
|
23908
|
+
if (args2.wake !== void 0) draftSendBody.wake = args2.wake;
|
|
23909
|
+
const r = await apiRequest("POST", `/drafts/${args2.id}/send`, draftSendBody);
|
|
23857
23910
|
return `Draft sent. Message ID: ${r?.messageId ?? "unknown"}`;
|
|
23858
23911
|
}
|
|
23859
23912
|
if (args2.action === "delete") {
|
|
@@ -24459,12 +24512,14 @@ ${lines.join("\n\n---\n\n")}`;
|
|
|
24459
24512
|
${lines.join("\n")}`;
|
|
24460
24513
|
}
|
|
24461
24514
|
case "template_send": {
|
|
24462
|
-
const
|
|
24515
|
+
const templateBody = {
|
|
24463
24516
|
to: args2.to,
|
|
24464
24517
|
variables: args2.variables,
|
|
24465
24518
|
cc: args2.cc,
|
|
24466
24519
|
bcc: args2.bcc
|
|
24467
|
-
}
|
|
24520
|
+
};
|
|
24521
|
+
if (args2.wake !== void 0) templateBody.wake = args2.wake;
|
|
24522
|
+
const result = await apiRequest("POST", `/templates/${args2.id}/send`, templateBody);
|
|
24468
24523
|
return `Template email sent. Message ID: ${result?.messageId ?? "unknown"}`;
|
|
24469
24524
|
}
|
|
24470
24525
|
case "manage_rules": {
|
|
@@ -24519,6 +24574,38 @@ ${r.agents.map(
|
|
|
24519
24574
|
}
|
|
24520
24575
|
throw new Error("Invalid action. Use: list_inactive, cleanup, or set_persistent");
|
|
24521
24576
|
}
|
|
24577
|
+
case "check_activity": {
|
|
24578
|
+
const r = await apiRequest("GET", "/dispatcher/activity", void 0, true);
|
|
24579
|
+
const filterAgent = typeof args2.agent === "string" ? args2.agent.toLowerCase() : "";
|
|
24580
|
+
const includeRecent = args2.includeRecent !== false;
|
|
24581
|
+
const matchesFilter = (w) => !filterAgent || (w.agentName ?? "").toLowerCase().includes(filterAgent);
|
|
24582
|
+
const activeList = Array.isArray(r?.active) ? r.active.filter(matchesFilter) : [];
|
|
24583
|
+
const recentList = includeRecent && Array.isArray(r?.recent) ? r.recent.filter(matchesFilter) : [];
|
|
24584
|
+
if (activeList.length === 0 && recentList.length === 0) {
|
|
24585
|
+
if (filterAgent) return `No dispatcher activity for "${args2.agent}" right now or in the last 2 minutes. Either the agent has not been woken on this thread yet, the dispatcher is not running, or mail to them is still in flight.`;
|
|
24586
|
+
return "No dispatcher activity right now or in the last 2 minutes. If you just sent mail and expected an agent to wake, give it a moment \u2014 the dispatcher subscribes to /system/events for sub-second wake. If nothing happens for 30s, check that the dispatcher process is running (`pm2 list`) and that the recipient is a real local agent (`list_agents`).";
|
|
24587
|
+
}
|
|
24588
|
+
const fmt = (w, prefix) => {
|
|
24589
|
+
const dur = w.durationMs ? `${(w.durationMs / 1e3).toFixed(1)}s` : "?";
|
|
24590
|
+
const trig = w.trigger?.subject ? ` \u2014 ${String(w.trigger.subject).slice(0, 60)}` : w.trigger?.taskId ? ` \u2014 task ${String(w.trigger.taskId).slice(0, 8)}` : "";
|
|
24591
|
+
const from = w.trigger?.from ? ` (from ${w.trigger.from})` : "";
|
|
24592
|
+
const preview = w.resultPreview ? `
|
|
24593
|
+
\u2192 ${String(w.resultPreview).slice(0, 140).replace(/\s+/g, " ").trim()}` : "";
|
|
24594
|
+
const status = w.endedAtMs ? w.ok === false ? "failed" : "finished" : "running";
|
|
24595
|
+
return ` ${prefix} ${w.agentName} [${w.kind}] ${status} ${dur}${trig}${from}${preview}`;
|
|
24596
|
+
};
|
|
24597
|
+
const lines = [];
|
|
24598
|
+
if (activeList.length > 0) {
|
|
24599
|
+
lines.push(`Active workers (${activeList.length}):`);
|
|
24600
|
+
for (const w of activeList) lines.push(fmt(w, "\u25CF"));
|
|
24601
|
+
}
|
|
24602
|
+
if (recentList.length > 0) {
|
|
24603
|
+
if (lines.length > 0) lines.push("");
|
|
24604
|
+
lines.push(`Recently finished (last 2 min, ${recentList.length}):`);
|
|
24605
|
+
for (const w of recentList) lines.push(fmt(w, "\u25CB"));
|
|
24606
|
+
}
|
|
24607
|
+
return lines.join("\n");
|
|
24608
|
+
}
|
|
24522
24609
|
case "check_tasks": {
|
|
24523
24610
|
let endpoint = args2.direction === "outgoing" ? "/tasks/assigned" : "/tasks/pending";
|
|
24524
24611
|
if (args2.direction !== "outgoing" && args2.assignee) {
|
|
@@ -25069,6 +25156,7 @@ var SERVER_INSTRUCTIONS = [
|
|
|
25069
25156
|
' to: "vesper@localhost", // primary owner of step 1',
|
|
25070
25157
|
' cc: "orion@localhost, claudecode@localhost", // teammates + yourself',
|
|
25071
25158
|
' subject: "Build a small terminal game",',
|
|
25159
|
+
' wake: ["vesper"], // only Vesper gets a Claude turn',
|
|
25072
25160
|
" text: [",
|
|
25073
25161
|
' "Team \u2014",',
|
|
25074
25162
|
' "",',
|
|
@@ -25081,6 +25169,14 @@ var SERVER_INSTRUCTIONS = [
|
|
|
25081
25169
|
' ].join("\\n"),',
|
|
25082
25170
|
" })",
|
|
25083
25171
|
"",
|
|
25172
|
+
" The `wake` parameter is the SINGLE BIGGEST TOKEN SAVER on large threads.",
|
|
25173
|
+
" Without it, every CC'd recipient burns one Claude turn deciding whether",
|
|
25174
|
+
" it is their turn. With it, only the named agents get a turn \u2014 the rest",
|
|
25175
|
+
" receive the mail in their inbox but stay asleep until you (or another",
|
|
25176
|
+
" agent) explicitly names them in a later `wake` list. Pass `wake: []`",
|
|
25177
|
+
' for "deliver silently \u2014 wake nobody". Omit `wake` entirely to keep the',
|
|
25178
|
+
` old "wake every CC'd agent" behaviour (backwards compatible).`,
|
|
25179
|
+
"",
|
|
25084
25180
|
" The mail server pushes a wake-up to every local recipient simultaneously.",
|
|
25085
25181
|
" Each agent reads the thread, decides if it is THEIR turn, and either",
|
|
25086
25182
|
" reply-all's to contribute or stays silent. Vesper goes first because she",
|
|
@@ -25100,7 +25196,15 @@ var SERVER_INSTRUCTIONS = [
|
|
|
25100
25196
|
" To unblock a stuck agent or change direction, just reply-all into the",
|
|
25101
25197
|
" same thread.",
|
|
25102
25198
|
"",
|
|
25103
|
-
|
|
25199
|
+
"4. **Close the thread when work is complete.** Send a wrap-up reply",
|
|
25200
|
+
" with one of these markers in the subject: `[FINAL]`, `[DONE]`,",
|
|
25201
|
+
" `[CLOSED]`, or `[WRAP]`. The dispatcher honours those markers and",
|
|
25202
|
+
" stops waking workers on any further replies to that thread. Without",
|
|
25203
|
+
" this, the cascade can keep firing as agents critique each other's",
|
|
25204
|
+
" work even after the deliverables are in. Add the marker once, the",
|
|
25205
|
+
" thread is sealed.",
|
|
25206
|
+
"",
|
|
25207
|
+
'5. Done when the last hand-off (or an explicit "complete" message) lands',
|
|
25104
25208
|
" in your inbox. Show the result to the user.",
|
|
25105
25209
|
"",
|
|
25106
25210
|
"Why this is right:",
|