agenthub-multiagent-mcp 1.69.0 → 1.71.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.
@@ -22,6 +22,7 @@ import { promises as fsp } from "node:fs";
22
22
  import * as os from "node:os";
23
23
  import * as path from "node:path";
24
24
  import { describeSendResult } from "../messageIdempotency.js";
25
+ import { readZohoAttachments } from "../zohoAttachments.js";
25
26
  // fix-message-send-idempotency — shared by the four message tools.
26
27
  const IDEMPOTENCY_KEY_DESCRIPTION = "Optional. Leave unset: a key derived from the message content is sent, so " +
27
28
  "re-issuing this exact call (e.g. after a timeout) never delivers it twice. " +
@@ -3012,18 +3013,49 @@ export function registerTools() {
3012
3013
  },
3013
3014
  {
3014
3015
  name: "zoho_send_email",
3015
- description: "Send an email from one of your registered mailboxes. Behaviour depends on the mailbox's send_mode: 'direct' dispatches (governed by the recipient allowlist + daily cap); 'draft_only' saves a draft to your Zoho Drafts and does NOT send — you send it yourself from Zoho web. (requires agent_register first)",
3016
+ description: "Compose from one of your registered mailboxes: a new message or a reply in an existing thread, " +
3017
+ "with optional cc/bcc and local file attachments. mode 'draft' (default) saves to your Zoho Drafts; " +
3018
+ "'send' dispatches, but only from a mailbox whose send_mode is 'direct' (governed by the recipient " +
3019
+ "allowlist, applied to every to/cc/bcc address, and the daily cap). A draft_only mailbox refuses " +
3020
+ "'send' with mailbox_draft_only rather than drafting silently — you send it yourself from Zoho web. " +
3021
+ "To reply: pass in_reply_to (message id) and folder (folder id) as zoho_list_messages / zoho_search " +
3022
+ "return them; the reply threads, subject defaults to 'Re: <original>', and to defaults to the sender. " +
3023
+ "reply_all also addresses the original's to + cc (minus your mailbox); any to/cc you pass are added. " +
3024
+ "attachments are LOCAL file paths (max 10 files, 7 MB in total), checked before anything is sent. " +
3025
+ "(requires agent_register first)",
3016
3026
  inputSchema: {
3017
3027
  type: "object",
3018
3028
  properties: {
3019
3029
  mailbox: { type: "string", description: "Your mailbox address" },
3020
- to: { type: "array", items: { type: "string" }, description: "Recipient email addresses" },
3021
- subject: { type: "string", description: "Subject line" },
3030
+ to: {
3031
+ type: "array",
3032
+ items: { type: "string" },
3033
+ description: "Recipient addresses. Required unless in_reply_to is set.",
3034
+ },
3035
+ cc: { type: "array", items: { type: "string" }, description: "Cc addresses" },
3036
+ bcc: { type: "array", items: { type: "string" }, description: "Bcc addresses" },
3037
+ subject: { type: "string", description: "Subject line. Optional for a reply." },
3022
3038
  body_text: { type: "string", description: "Plain-text body" },
3023
3039
  body_html: { type: "string", description: "HTML body (overrides body_text format)" },
3040
+ attachments: {
3041
+ type: "array",
3042
+ items: { type: "string" },
3043
+ description: "Local file paths to attach (read on this machine)",
3044
+ },
3045
+ in_reply_to: { type: "string", description: "Zoho message id to reply to (threads the result)" },
3046
+ folder: { type: "string", description: "Folder id of the in_reply_to message (required with it)" },
3047
+ reply_all: {
3048
+ type: "boolean",
3049
+ description: "With in_reply_to: also address the original's to and cc",
3050
+ },
3051
+ mode: {
3052
+ type: "string",
3053
+ enum: ["draft", "send"],
3054
+ description: "draft (default) saves to Drafts; send dispatches (direct mailboxes only)",
3055
+ },
3024
3056
  dedupe_key: { type: "string", description: "Optional idempotency key (direct sends)" },
3025
3057
  },
3026
- required: ["mailbox", "to", "subject"],
3058
+ required: ["mailbox"],
3027
3059
  },
3028
3060
  },
3029
3061
  {
@@ -5491,17 +5523,28 @@ export async function handleToolCall(name, args, client, context) {
5491
5523
  case "zoho_send_email": {
5492
5524
  if (!agentId)
5493
5525
  throw new Error("Not registered. Call agent_register first.");
5526
+ // Read and check every local file before any request (never a partial send).
5527
+ const attachments = readZohoAttachments(args.attachments);
5494
5528
  const res = await client.zohoSend({
5495
5529
  mailbox: args.mailbox,
5496
5530
  to: args.to,
5531
+ cc: args.cc,
5532
+ bcc: args.bcc,
5497
5533
  subject: args.subject,
5498
5534
  body_text: args.body_text,
5499
5535
  body_html: args.body_html,
5536
+ attachments: attachments.length > 0 ? attachments : undefined,
5537
+ in_reply_to: args.in_reply_to,
5538
+ folder: args.folder,
5539
+ reply_all: args.reply_all,
5540
+ mode: args.mode,
5500
5541
  dedupe_key: args.dedupe_key,
5501
5542
  });
5543
+ const extras = (res.threaded ? " Threaded as a reply." : "") +
5544
+ (attachments.length > 0 ? ` ${attachments.length} attachment(s).` : "");
5502
5545
  const msg = res.dispatched
5503
- ? `Sent from ${args.mailbox} (message id ${res.message_id}).`
5504
- : `Draft saved in ${args.mailbox} (id ${res.message_id}). ${res.note ?? "Send it yourself from Zoho web."}`;
5546
+ ? `Sent from ${args.mailbox} (message id ${res.message_id}).${extras}`
5547
+ : `Draft saved in ${args.mailbox} (id ${res.message_id}).${extras} ${res.note ?? "Send it yourself from Zoho web."}`;
5505
5548
  return { content: [{ type: "text", text: msg }] };
5506
5549
  }
5507
5550
  case "zoho_mark_read": {