@agenticmail/mcp 0.9.5 → 0.9.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.
Files changed (2) hide show
  1. package/dist/index.js +338 -73
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3105,6 +3105,9 @@ var require_utils = __commonJS({
3105
3105
  "use strict";
3106
3106
  var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
3107
3107
  var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
3108
+ var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
3109
+ var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
3110
+ var isPathCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/]$/iu);
3108
3111
  function stringArrayToHexStripped(input) {
3109
3112
  let acc = "";
3110
3113
  let code = 0;
@@ -3297,27 +3300,77 @@ var require_utils = __commonJS({
3297
3300
  }
3298
3301
  return output.join("");
3299
3302
  }
3300
- function normalizeComponentEncoding(component, esc2) {
3301
- const func = esc2 !== true ? escape : unescape;
3302
- if (component.scheme !== void 0) {
3303
- component.scheme = func(component.scheme);
3304
- }
3305
- if (component.userinfo !== void 0) {
3306
- component.userinfo = func(component.userinfo);
3307
- }
3308
- if (component.host !== void 0) {
3309
- component.host = func(component.host);
3303
+ var HOST_DELIMS = { "@": "%40", "/": "%2F", "?": "%3F", "#": "%23", ":": "%3A" };
3304
+ var HOST_DELIM_RE = /[@/?#:]/g;
3305
+ var HOST_DELIM_NO_COLON_RE = /[@/?#]/g;
3306
+ function reescapeHostDelimiters(host, isIP) {
3307
+ const re = isIP ? HOST_DELIM_NO_COLON_RE : HOST_DELIM_RE;
3308
+ re.lastIndex = 0;
3309
+ return host.replace(re, (ch) => HOST_DELIMS[ch]);
3310
+ }
3311
+ function normalizePercentEncoding(input, decodeUnreserved = false) {
3312
+ if (input.indexOf("%") === -1) {
3313
+ return input;
3310
3314
  }
3311
- if (component.path !== void 0) {
3312
- component.path = func(component.path);
3315
+ let output = "";
3316
+ for (let i = 0; i < input.length; i++) {
3317
+ if (input[i] === "%" && i + 2 < input.length) {
3318
+ const hex = input.slice(i + 1, i + 3);
3319
+ if (isHexPair(hex)) {
3320
+ const normalizedHex = hex.toUpperCase();
3321
+ const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
3322
+ if (decodeUnreserved && isUnreserved(decoded)) {
3323
+ output += decoded;
3324
+ } else {
3325
+ output += "%" + normalizedHex;
3326
+ }
3327
+ i += 2;
3328
+ continue;
3329
+ }
3330
+ }
3331
+ output += input[i];
3313
3332
  }
3314
- if (component.query !== void 0) {
3315
- component.query = func(component.query);
3333
+ return output;
3334
+ }
3335
+ function normalizePathEncoding(input) {
3336
+ let output = "";
3337
+ for (let i = 0; i < input.length; i++) {
3338
+ if (input[i] === "%" && i + 2 < input.length) {
3339
+ const hex = input.slice(i + 1, i + 3);
3340
+ if (isHexPair(hex)) {
3341
+ const normalizedHex = hex.toUpperCase();
3342
+ const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
3343
+ if (decoded !== "." && isUnreserved(decoded)) {
3344
+ output += decoded;
3345
+ } else {
3346
+ output += "%" + normalizedHex;
3347
+ }
3348
+ i += 2;
3349
+ continue;
3350
+ }
3351
+ }
3352
+ if (isPathCharacter(input[i])) {
3353
+ output += input[i];
3354
+ } else {
3355
+ output += escape(input[i]);
3356
+ }
3316
3357
  }
3317
- if (component.fragment !== void 0) {
3318
- component.fragment = func(component.fragment);
3358
+ return output;
3359
+ }
3360
+ function escapePreservingEscapes(input) {
3361
+ let output = "";
3362
+ for (let i = 0; i < input.length; i++) {
3363
+ if (input[i] === "%" && i + 2 < input.length) {
3364
+ const hex = input.slice(i + 1, i + 3);
3365
+ if (isHexPair(hex)) {
3366
+ output += "%" + hex.toUpperCase();
3367
+ i += 2;
3368
+ continue;
3369
+ }
3370
+ }
3371
+ output += escape(input[i]);
3319
3372
  }
3320
- return component;
3373
+ return output;
3321
3374
  }
3322
3375
  function recomposeAuthority(component) {
3323
3376
  const uriTokens = [];
@@ -3332,7 +3385,7 @@ var require_utils = __commonJS({
3332
3385
  if (ipV6res.isIPV6 === true) {
3333
3386
  host = `[${ipV6res.escapedHost}]`;
3334
3387
  } else {
3335
- host = component.host;
3388
+ host = reescapeHostDelimiters(host, false);
3336
3389
  }
3337
3390
  }
3338
3391
  uriTokens.push(host);
@@ -3346,7 +3399,10 @@ var require_utils = __commonJS({
3346
3399
  module.exports = {
3347
3400
  nonSimpleDomain,
3348
3401
  recomposeAuthority,
3349
- normalizeComponentEncoding,
3402
+ reescapeHostDelimiters,
3403
+ normalizePercentEncoding,
3404
+ normalizePathEncoding,
3405
+ escapePreservingEscapes,
3350
3406
  removeDotSegments,
3351
3407
  isIPv4,
3352
3408
  isUUID,
@@ -3570,12 +3626,12 @@ var require_schemes = __commonJS({
3570
3626
  var require_fast_uri = __commonJS({
3571
3627
  "../../node_modules/fast-uri/index.js"(exports, module) {
3572
3628
  "use strict";
3573
- var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4, nonSimpleDomain } = require_utils();
3629
+ var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
3574
3630
  var { SCHEMES, getSchemeHandler } = require_schemes();
3575
3631
  function normalize(uri, options) {
3576
3632
  if (typeof uri === "string") {
3577
3633
  uri = /** @type {T} */
3578
- serialize(parse3(uri, options), options);
3634
+ normalizeString(uri, options);
3579
3635
  } else if (typeof uri === "object") {
3580
3636
  uri = /** @type {T} */
3581
3637
  parse3(serialize(uri, options), options);
@@ -3642,19 +3698,9 @@ var require_fast_uri = __commonJS({
3642
3698
  return target;
3643
3699
  }
3644
3700
  function equal(uriA, uriB, options) {
3645
- if (typeof uriA === "string") {
3646
- uriA = unescape(uriA);
3647
- uriA = serialize(normalizeComponentEncoding(parse3(uriA, options), true), { ...options, skipEscape: true });
3648
- } else if (typeof uriA === "object") {
3649
- uriA = serialize(normalizeComponentEncoding(uriA, true), { ...options, skipEscape: true });
3650
- }
3651
- if (typeof uriB === "string") {
3652
- uriB = unescape(uriB);
3653
- uriB = serialize(normalizeComponentEncoding(parse3(uriB, options), true), { ...options, skipEscape: true });
3654
- } else if (typeof uriB === "object") {
3655
- uriB = serialize(normalizeComponentEncoding(uriB, true), { ...options, skipEscape: true });
3656
- }
3657
- return uriA.toLowerCase() === uriB.toLowerCase();
3701
+ const normalizedA = normalizeComparableURI(uriA, options);
3702
+ const normalizedB = normalizeComparableURI(uriB, options);
3703
+ return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA.toLowerCase() === normalizedB.toLowerCase();
3658
3704
  }
3659
3705
  function serialize(cmpts, opts) {
3660
3706
  const component = {
@@ -3679,12 +3725,12 @@ var require_fast_uri = __commonJS({
3679
3725
  if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
3680
3726
  if (component.path !== void 0) {
3681
3727
  if (!options.skipEscape) {
3682
- component.path = escape(component.path);
3728
+ component.path = escapePreservingEscapes(component.path);
3683
3729
  if (component.scheme !== void 0) {
3684
3730
  component.path = component.path.split("%3A").join(":");
3685
3731
  }
3686
3732
  } else {
3687
- component.path = unescape(component.path);
3733
+ component.path = normalizePercentEncoding(component.path);
3688
3734
  }
3689
3735
  }
3690
3736
  if (options.reference !== "suffix" && component.scheme) {
@@ -3719,7 +3765,16 @@ var require_fast_uri = __commonJS({
3719
3765
  return uriTokens.join("");
3720
3766
  }
3721
3767
  var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
3722
- function parse3(uri, opts) {
3768
+ function getParseError(parsed, matches) {
3769
+ if (matches[2] !== void 0 && parsed.path && parsed.path[0] !== "/") {
3770
+ return 'URI path must start with "/" when authority is present.';
3771
+ }
3772
+ if (typeof parsed.port === "number" && (parsed.port < 0 || parsed.port > 65535)) {
3773
+ return "URI port is malformed.";
3774
+ }
3775
+ return void 0;
3776
+ }
3777
+ function parseWithStatus(uri, opts) {
3723
3778
  const options = Object.assign({}, opts);
3724
3779
  const parsed = {
3725
3780
  scheme: void 0,
@@ -3730,6 +3785,7 @@ var require_fast_uri = __commonJS({
3730
3785
  query: void 0,
3731
3786
  fragment: void 0
3732
3787
  };
3788
+ let malformedAuthorityOrPort = false;
3733
3789
  let isIP = false;
3734
3790
  if (options.reference === "suffix") {
3735
3791
  if (options.scheme) {
@@ -3750,6 +3806,11 @@ var require_fast_uri = __commonJS({
3750
3806
  if (isNaN(parsed.port)) {
3751
3807
  parsed.port = matches[5];
3752
3808
  }
3809
+ const parseError = getParseError(parsed, matches);
3810
+ if (parseError !== void 0) {
3811
+ parsed.error = parsed.error || parseError;
3812
+ malformedAuthorityOrPort = true;
3813
+ }
3753
3814
  if (parsed.host) {
3754
3815
  const ipv4result = isIPv4(parsed.host);
3755
3816
  if (ipv4result === false) {
@@ -3788,14 +3849,18 @@ var require_fast_uri = __commonJS({
3788
3849
  parsed.scheme = unescape(parsed.scheme);
3789
3850
  }
3790
3851
  if (parsed.host !== void 0) {
3791
- parsed.host = unescape(parsed.host);
3852
+ parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP);
3792
3853
  }
3793
3854
  }
3794
3855
  if (parsed.path) {
3795
- parsed.path = escape(unescape(parsed.path));
3856
+ parsed.path = normalizePathEncoding(parsed.path);
3796
3857
  }
3797
3858
  if (parsed.fragment) {
3798
- parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
3859
+ try {
3860
+ parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
3861
+ } catch {
3862
+ parsed.error = parsed.error || "URI malformed";
3863
+ }
3799
3864
  }
3800
3865
  }
3801
3866
  if (schemeHandler && schemeHandler.parse) {
@@ -3804,7 +3869,29 @@ var require_fast_uri = __commonJS({
3804
3869
  } else {
3805
3870
  parsed.error = parsed.error || "URI can not be parsed.";
3806
3871
  }
3807
- return parsed;
3872
+ return { parsed, malformedAuthorityOrPort };
3873
+ }
3874
+ function parse3(uri, opts) {
3875
+ return parseWithStatus(uri, opts).parsed;
3876
+ }
3877
+ function normalizeString(uri, opts) {
3878
+ return normalizeStringWithStatus(uri, opts).normalized;
3879
+ }
3880
+ function normalizeStringWithStatus(uri, opts) {
3881
+ const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
3882
+ return {
3883
+ normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
3884
+ malformedAuthorityOrPort
3885
+ };
3886
+ }
3887
+ function normalizeComparableURI(uri, opts) {
3888
+ if (typeof uri === "string") {
3889
+ const { normalized, malformedAuthorityOrPort } = normalizeStringWithStatus(uri, opts);
3890
+ return malformedAuthorityOrPort ? void 0 : normalized;
3891
+ }
3892
+ if (typeof uri === "object") {
3893
+ return serialize(uri, opts);
3894
+ }
3808
3895
  }
3809
3896
  var fastUri = {
3810
3897
  SCHEMES,
@@ -3944,7 +4031,7 @@ var require_core = __commonJS({
3944
4031
  constructor(opts = {}) {
3945
4032
  this.schemas = {};
3946
4033
  this.refs = {};
3947
- this.formats = {};
4034
+ this.formats = /* @__PURE__ */ Object.create(null);
3948
4035
  this._compilations = /* @__PURE__ */ new Set();
3949
4036
  this._loading = {};
3950
4037
  this._cache = /* @__PURE__ */ new Map();
@@ -4725,6 +4812,7 @@ var require_pattern = __commonJS({
4725
4812
  "use strict";
4726
4813
  Object.defineProperty(exports, "__esModule", { value: true });
4727
4814
  var code_1 = require_code2();
4815
+ var util_1 = require_util();
4728
4816
  var codegen_1 = require_codegen();
4729
4817
  var error2 = {
4730
4818
  message: ({ schemaCode }) => (0, codegen_1.str)`must match pattern "${schemaCode}"`,
@@ -4737,10 +4825,18 @@ var require_pattern = __commonJS({
4737
4825
  $data: true,
4738
4826
  error: error2,
4739
4827
  code(cxt) {
4740
- const { data, $data, schema, schemaCode, it } = cxt;
4828
+ const { gen, data, $data, schema, schemaCode, it } = cxt;
4741
4829
  const u = it.opts.unicodeRegExp ? "u" : "";
4742
- const regExp = $data ? (0, codegen_1._)`(new RegExp(${schemaCode}, ${u}))` : (0, code_1.usePattern)(cxt, schema);
4743
- cxt.fail$data((0, codegen_1._)`!${regExp}.test(${data})`);
4830
+ if ($data) {
4831
+ const { regExp } = it.opts.code;
4832
+ const regExpCode = regExp.code === "new RegExp" ? (0, codegen_1._)`new RegExp` : (0, util_1.useFunc)(gen, regExp);
4833
+ const valid = gen.let("valid");
4834
+ gen.try(() => gen.assign(valid, (0, codegen_1._)`${regExpCode}(${schemaCode}, ${u}).test(${data})`), () => gen.assign(valid, false));
4835
+ cxt.fail$data((0, codegen_1._)`!${valid}`);
4836
+ } else {
4837
+ const regExp = (0, code_1.usePattern)(cxt, schema);
4838
+ cxt.fail$data((0, codegen_1._)`!${regExp}.test(${data})`);
4839
+ }
4744
4840
  }
4745
4841
  };
4746
4842
  exports.default = def;
@@ -21004,7 +21100,7 @@ var StdioServerTransport = class {
21004
21100
  };
21005
21101
 
21006
21102
  // ../../node_modules/@hono/node-server/dist/index.mjs
21007
- import { Http2ServerRequest as Http2ServerRequest2 } from "http2";
21103
+ import { Http2ServerRequest as Http2ServerRequest2, constants as h2constants } from "http2";
21008
21104
  import { Http2ServerRequest } from "http2";
21009
21105
  import { Readable } from "stream";
21010
21106
  import crypto2 from "crypto";
@@ -21152,6 +21248,17 @@ var requestPrototype = {
21152
21248
  }
21153
21249
  });
21154
21250
  });
21251
+ Object.defineProperty(requestPrototype, /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom"), {
21252
+ value: function(depth, options, inspectFn) {
21253
+ const props = {
21254
+ method: this.method,
21255
+ url: this.url,
21256
+ headers: this.headers,
21257
+ nativeRequest: this[requestCache]
21258
+ };
21259
+ return `Request (lightweight) ${inspectFn(props, { ...options, depth: depth == null ? null : depth - 1 })}`;
21260
+ }
21261
+ });
21155
21262
  Object.setPrototypeOf(requestPrototype, Request.prototype);
21156
21263
  var newRequest = (incoming, defaultHostname) => {
21157
21264
  const req = Object.create(requestPrototype);
@@ -21218,15 +21325,17 @@ var Response2 = class _Response {
21218
21325
  this.#init = init;
21219
21326
  }
21220
21327
  if (typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) {
21221
- headers ||= init?.headers || { "content-type": "text/plain; charset=UTF-8" };
21222
- this[cacheKey] = [init?.status || 200, body, headers];
21328
+ ;
21329
+ this[cacheKey] = [init?.status || 200, body, headers || init?.headers];
21223
21330
  }
21224
21331
  }
21225
21332
  get headers() {
21226
21333
  const cache = this[cacheKey];
21227
21334
  if (cache) {
21228
21335
  if (!(cache[2] instanceof Headers)) {
21229
- cache[2] = new Headers(cache[2]);
21336
+ cache[2] = new Headers(
21337
+ cache[2] || { "content-type": "text/plain; charset=UTF-8" }
21338
+ );
21230
21339
  }
21231
21340
  return cache[2];
21232
21341
  }
@@ -21254,6 +21363,17 @@ var Response2 = class _Response {
21254
21363
  }
21255
21364
  });
21256
21365
  });
21366
+ Object.defineProperty(Response2.prototype, /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom"), {
21367
+ value: function(depth, options, inspectFn) {
21368
+ const props = {
21369
+ status: this.status,
21370
+ headers: this.headers,
21371
+ ok: this.ok,
21372
+ nativeResponse: this[responseCache]
21373
+ };
21374
+ return `Response (lightweight) ${inspectFn(props, { ...options, depth: depth == null ? null : depth - 1 })}`;
21375
+ }
21376
+ });
21257
21377
  Object.setPrototypeOf(Response2, GlobalResponse);
21258
21378
  Object.setPrototypeOf(Response2.prototype, GlobalResponse.prototype);
21259
21379
  async function readWithoutBlocking(readPromise) {
@@ -21325,6 +21445,50 @@ if (typeof global.crypto === "undefined") {
21325
21445
  global.crypto = crypto2;
21326
21446
  }
21327
21447
  var outgoingEnded = /* @__PURE__ */ Symbol("outgoingEnded");
21448
+ var incomingDraining = /* @__PURE__ */ Symbol("incomingDraining");
21449
+ var DRAIN_TIMEOUT_MS = 500;
21450
+ var MAX_DRAIN_BYTES = 64 * 1024 * 1024;
21451
+ var drainIncoming = (incoming) => {
21452
+ const incomingWithDrainState = incoming;
21453
+ if (incoming.destroyed || incomingWithDrainState[incomingDraining]) {
21454
+ return;
21455
+ }
21456
+ incomingWithDrainState[incomingDraining] = true;
21457
+ if (incoming instanceof Http2ServerRequest2) {
21458
+ try {
21459
+ ;
21460
+ incoming.stream?.close?.(h2constants.NGHTTP2_NO_ERROR);
21461
+ } catch {
21462
+ }
21463
+ return;
21464
+ }
21465
+ let bytesRead = 0;
21466
+ const cleanup = () => {
21467
+ clearTimeout(timer);
21468
+ incoming.off("data", onData);
21469
+ incoming.off("end", cleanup);
21470
+ incoming.off("error", cleanup);
21471
+ };
21472
+ const forceClose = () => {
21473
+ cleanup();
21474
+ const socket = incoming.socket;
21475
+ if (socket && !socket.destroyed) {
21476
+ socket.destroySoon();
21477
+ }
21478
+ };
21479
+ const timer = setTimeout(forceClose, DRAIN_TIMEOUT_MS);
21480
+ timer.unref?.();
21481
+ const onData = (chunk) => {
21482
+ bytesRead += chunk.length;
21483
+ if (bytesRead > MAX_DRAIN_BYTES) {
21484
+ forceClose();
21485
+ }
21486
+ };
21487
+ incoming.on("data", onData);
21488
+ incoming.on("end", cleanup);
21489
+ incoming.on("error", cleanup);
21490
+ incoming.resume();
21491
+ };
21328
21492
  var handleRequestError = () => new Response(null, {
21329
21493
  status: 400
21330
21494
  });
@@ -21351,15 +21515,32 @@ var flushHeaders = (outgoing) => {
21351
21515
  };
21352
21516
  var responseViaCache = async (res, outgoing) => {
21353
21517
  let [status, body, header] = res[cacheKey];
21354
- if (header instanceof Headers) {
21518
+ let hasContentLength = false;
21519
+ if (!header) {
21520
+ header = { "content-type": "text/plain; charset=UTF-8" };
21521
+ } else if (header instanceof Headers) {
21522
+ hasContentLength = header.has("content-length");
21355
21523
  header = buildOutgoingHttpHeaders(header);
21524
+ } else if (Array.isArray(header)) {
21525
+ const headerObj = new Headers(header);
21526
+ hasContentLength = headerObj.has("content-length");
21527
+ header = buildOutgoingHttpHeaders(headerObj);
21528
+ } else {
21529
+ for (const key in header) {
21530
+ if (key.length === 14 && key.toLowerCase() === "content-length") {
21531
+ hasContentLength = true;
21532
+ break;
21533
+ }
21534
+ }
21356
21535
  }
21357
- if (typeof body === "string") {
21358
- header["Content-Length"] = Buffer.byteLength(body);
21359
- } else if (body instanceof Uint8Array) {
21360
- header["Content-Length"] = body.byteLength;
21361
- } else if (body instanceof Blob) {
21362
- header["Content-Length"] = body.size;
21536
+ if (!hasContentLength) {
21537
+ if (typeof body === "string") {
21538
+ header["Content-Length"] = Buffer.byteLength(body);
21539
+ } else if (body instanceof Uint8Array) {
21540
+ header["Content-Length"] = body.byteLength;
21541
+ } else if (body instanceof Blob) {
21542
+ header["Content-Length"] = body.size;
21543
+ }
21363
21544
  }
21364
21545
  outgoing.writeHead(status, header);
21365
21546
  if (typeof body === "string" || body instanceof Uint8Array) {
@@ -21479,14 +21660,18 @@ var getRequestListener = (fetchCallback, options = {}) => {
21479
21660
  setTimeout(() => {
21480
21661
  if (!incomingEnded) {
21481
21662
  setTimeout(() => {
21482
- incoming.destroy();
21483
- outgoing.destroy();
21663
+ drainIncoming(incoming);
21484
21664
  });
21485
21665
  }
21486
21666
  });
21487
21667
  }
21488
21668
  };
21489
21669
  }
21670
+ outgoing.on("finish", () => {
21671
+ if (!incomingEnded) {
21672
+ drainIncoming(incoming);
21673
+ }
21674
+ });
21490
21675
  }
21491
21676
  outgoing.on("close", () => {
21492
21677
  const abortController = req[abortControllerKey];
@@ -21501,7 +21686,7 @@ var getRequestListener = (fetchCallback, options = {}) => {
21501
21686
  setTimeout(() => {
21502
21687
  if (!incomingEnded) {
21503
21688
  setTimeout(() => {
21504
- incoming.destroy();
21689
+ drainIncoming(incoming);
21505
21690
  });
21506
21691
  }
21507
21692
  });
@@ -22527,6 +22712,27 @@ var ESSENTIAL_TOOLS = TOOL_SETS.essential;
22527
22712
  var API_URL = process.env.AGENTICMAIL_API_URL ?? "http://127.0.0.1:3829";
22528
22713
  var API_KEY = process.env.AGENTICMAIL_API_KEY ?? "";
22529
22714
  var MASTER_KEY = process.env.AGENTICMAIL_MASTER_KEY ?? "";
22715
+ var MCP_HOST = (process.env.AGENTICMAIL_MCP_HOST ?? "").trim().toLowerCase();
22716
+ function visibleToCallerHost(host) {
22717
+ if (!MCP_HOST) return true;
22718
+ if (!host) return true;
22719
+ return host.toLowerCase() === MCP_HOST;
22720
+ }
22721
+ async function assertHostOwnsAgent(target) {
22722
+ if (!MCP_HOST) return;
22723
+ if (!target) return;
22724
+ try {
22725
+ const info = await apiRequest("GET", `/accounts/directory/${encodeURIComponent(target)}`);
22726
+ const host = typeof info?.host === "string" ? info.host : null;
22727
+ if (!visibleToCallerHost(host)) {
22728
+ throw new Error(
22729
+ `Agent "${target}" is owned by host "${host}", not "${MCP_HOST}". Each host's MCP server only talks to its own teammates + unclaimed accounts. If you want to transfer this agent: \`agenticmail-${host} claim ${target} --unclaim\` then \`agenticmail-${MCP_HOST} claim ${target}\`.`
22730
+ );
22731
+ }
22732
+ } catch (err) {
22733
+ if (err instanceof Error && err.message.includes("owned by host")) throw err;
22734
+ }
22735
+ }
22530
22736
  var ACCOUNT_KEYS = /* @__PURE__ */ new Map();
22531
22737
  (() => {
22532
22738
  const raw = process.env.AGENTICMAIL_ACCOUNT_KEYS_JSON ?? "";
@@ -23779,10 +23985,16 @@ Connected account (${result.relayResults[0].account}): ${result.relayResults.len
23779
23985
  const subject = origSubject.startsWith("Re:") ? origSubject : `Re: ${origSubject}`;
23780
23986
  const refs = Array.isArray(original.references) ? [...original.references] : [];
23781
23987
  if (original.messageId) refs.push(original.messageId);
23988
+ const fmtAddrs = (arr) => (Array.isArray(arr) ? arr : []).map((a) => typeof a === "string" ? a : a?.address ?? "").filter(Boolean).join(", ");
23989
+ const origTo = fmtAddrs(original.to);
23990
+ const origCc = fmtAddrs(original.cc);
23991
+ const headerLines = [`On ${original.date}, ${replyTo} wrote:`];
23992
+ if (origTo) headerLines.push(`To: ${origTo}`);
23993
+ if (origCc) headerLines.push(`Cc: ${origCc}`);
23782
23994
  const quotedBody = (original.text || "").split("\n").map((l) => `> ${l}`).join("\n");
23783
23995
  const fullText = `${args2.text}
23784
23996
 
23785
- On ${original.date}, ${replyTo} wrote:
23997
+ ${headerLines.join("\n")}
23786
23998
  ${quotedBody}`;
23787
23999
  let to = replyTo;
23788
24000
  let cc;
@@ -24204,15 +24416,23 @@ ${lines.join("\n")}`;
24204
24416
  }
24205
24417
  case "list_agents": {
24206
24418
  const result = await apiRequest("GET", "/accounts/directory");
24207
- const agents = result?.agents ?? [];
24208
- if (agents.length === 0) return "No agents found.";
24209
- const lines = agents.map((a) => ` ${a.name} (${a.email}) \u2014 ${a.role}`);
24210
- return `Agents in the system:
24419
+ const allAgents = Array.isArray(result?.agents) ? result.agents : [];
24420
+ const agents = allAgents.filter((a) => visibleToCallerHost(a.host));
24421
+ if (agents.length === 0) {
24422
+ return MCP_HOST ? `No agents owned by host "${MCP_HOST}" (or unclaimed) found. Use \`agenticmail-${MCP_HOST} claim --all\` to take ownership of legacy agents.` : "No agents found.";
24423
+ }
24424
+ const lines = agents.map((a) => {
24425
+ const hostTag = a.host ? ` \xB7 host=${a.host}` : "";
24426
+ return ` ${a.name} (${a.email}) \u2014 ${a.role}${hostTag}`;
24427
+ });
24428
+ const header = MCP_HOST ? `Agents on host "${MCP_HOST}" (+ unclaimed):` : "Agents in the system:";
24429
+ return `${header}
24211
24430
  ${lines.join("\n")}`;
24212
24431
  }
24213
24432
  case "message_agent": {
24214
24433
  const agentName = String(args2.agent ?? "").toLowerCase().trim();
24215
24434
  if (!agentName) throw new Error("agent name is required");
24435
+ await assertHostOwnsAgent(agentName);
24216
24436
  try {
24217
24437
  await apiRequest("GET", `/accounts/directory/${encodeURIComponent(agentName)}`);
24218
24438
  } catch {
@@ -24248,6 +24468,7 @@ ${details.join("\n")}${more}`;
24248
24468
  case "delete_agent": {
24249
24469
  const agentName = String(args2.name ?? "").trim();
24250
24470
  if (!agentName) throw new Error("name is required");
24471
+ await assertHostOwnsAgent(agentName);
24251
24472
  const agents = await apiRequest("GET", "/accounts", void 0, true);
24252
24473
  const fullAgent = agents?.agents?.find((a) => a.name === agentName);
24253
24474
  if (!fullAgent) throw new Error(`Agent "${agentName}" not found`);
@@ -24610,26 +24831,54 @@ ${lines.join("\n")}`;
24610
24831
  throw new Error("Invalid action. Use: list, create, or delete");
24611
24832
  }
24612
24833
  case "cleanup_agents": {
24834
+ let visibleNames = null;
24835
+ if (MCP_HOST) {
24836
+ try {
24837
+ const dir = await apiRequest("GET", "/accounts/directory");
24838
+ visibleNames = new Set(
24839
+ (Array.isArray(dir?.agents) ? dir.agents : []).filter((a) => visibleToCallerHost(a.host)).map((a) => String(a.name ?? "").toLowerCase())
24840
+ );
24841
+ } catch {
24842
+ }
24843
+ }
24844
+ const visibleAgent = (a) => !visibleNames || visibleNames.has(String(a.name ?? "").toLowerCase());
24613
24845
  if (args2.action === "list_inactive") {
24614
24846
  const qs = args2.hours ? `?hours=${args2.hours}` : "";
24615
24847
  const r = await apiRequest("GET", `/accounts/inactive${qs}`, void 0, true);
24616
- if (!r?.agents?.length) return "No inactive agents found. All agents are either active or persistent.";
24617
- return `${r.count} inactive agent(s):
24618
- ${r.agents.map(
24848
+ const rows = (Array.isArray(r?.agents) ? r.agents : []).filter(visibleAgent);
24849
+ if (rows.length === 0) return "No inactive agents found. All agents are either active or persistent.";
24850
+ return `${rows.length} inactive agent(s):
24851
+ ${rows.map(
24619
24852
  (a) => ` ${a.name} (${a.email}) \u2014 last active: ${a.last_activity_at || "never"}, persistent: ${a.persistent}`
24620
24853
  ).join("\n")}`;
24621
24854
  }
24622
24855
  if (args2.action === "cleanup") {
24623
24856
  const r = await apiRequest("POST", "/accounts/cleanup", { hours: args2.hours, dryRun: args2.dryRun }, true);
24857
+ const candidates = (Array.isArray(r?.wouldDelete) ? r.wouldDelete : []).filter(visibleAgent);
24858
+ const deleted = (Array.isArray(r?.deleted) ? r.deleted : []).filter(
24859
+ (name2) => !visibleNames || visibleNames.has(String(name2).toLowerCase())
24860
+ );
24624
24861
  if (r?.dryRun) {
24625
- if (!r.count) return "No inactive agents to clean up. All agents are either active or persistent.";
24626
- return `Would delete ${r.count} agent(s): ${r.wouldDelete.map((a) => a.name).join(", ")}`;
24862
+ if (!candidates.length) return "No inactive agents to clean up. All agents are either active or persistent.";
24863
+ return `Would delete ${candidates.length} agent(s): ${candidates.map((a) => a.name).join(", ")}`;
24627
24864
  }
24628
- if (!r?.count) return "No inactive agents to clean up. All agents are either active or persistent.";
24629
- return `Deleted ${r.count} agent(s): ${r.deleted.join(", ")}`;
24865
+ if (!deleted.length) return "No inactive agents to clean up. All agents are either active or persistent.";
24866
+ return `Deleted ${deleted.length} agent(s): ${deleted.join(", ")}`;
24630
24867
  }
24631
24868
  if (args2.action === "set_persistent") {
24632
24869
  if (!args2.agentId) throw new Error("agentId is required");
24870
+ if (MCP_HOST) {
24871
+ try {
24872
+ const all = await apiRequest("GET", "/accounts", void 0, true);
24873
+ const agent = (all?.agents ?? []).find((a) => a.id === args2.agentId);
24874
+ const host = typeof agent?.metadata?.host === "string" ? agent.metadata.host : null;
24875
+ if (agent && !visibleToCallerHost(host)) {
24876
+ throw new Error(`Agent ${args2.agentId} (${agent.name}) is owned by host "${host}", not "${MCP_HOST}".`);
24877
+ }
24878
+ } catch (err) {
24879
+ if (err instanceof Error && err.message.includes("owned by host")) throw err;
24880
+ }
24881
+ }
24633
24882
  await apiRequest("PATCH", `/accounts/${args2.agentId}/persistent`, { persistent: args2.persistent !== false }, true);
24634
24883
  return `Agent ${args2.agentId} persistent flag set to ${args2.persistent !== false}`;
24635
24884
  }
@@ -24667,8 +24916,23 @@ ${r.tail.join("\n")}`;
24667
24916
  const filterAgent = typeof args2.agent === "string" ? args2.agent.toLowerCase() : "";
24668
24917
  const includeRecent = args2.includeRecent !== false;
24669
24918
  const matchesFilter = (w) => !filterAgent || (w.agentName ?? "").toLowerCase().includes(filterAgent);
24670
- const activeList = Array.isArray(r?.active) ? r.active.filter(matchesFilter) : [];
24671
- const recentList = includeRecent && Array.isArray(r?.recent) ? r.recent.filter(matchesFilter) : [];
24919
+ let visibleNames = null;
24920
+ if (MCP_HOST) {
24921
+ try {
24922
+ const dir = await apiRequest("GET", "/accounts/directory");
24923
+ visibleNames = new Set(
24924
+ (Array.isArray(dir?.agents) ? dir.agents : []).filter((a) => visibleToCallerHost(a.host)).map((a) => String(a.name ?? "").toLowerCase())
24925
+ );
24926
+ } catch {
24927
+ }
24928
+ }
24929
+ const visibleToHost = (w) => {
24930
+ if (!visibleNames) return true;
24931
+ return visibleNames.has(String(w.agentName ?? "").toLowerCase());
24932
+ };
24933
+ const matchesAll = (w) => matchesFilter(w) && visibleToHost(w);
24934
+ const activeList = Array.isArray(r?.active) ? r.active.filter(matchesAll) : [];
24935
+ const recentList = includeRecent && Array.isArray(r?.recent) ? r.recent.filter(matchesAll) : [];
24672
24936
  if (activeList.length === 0 && recentList.length === 0) {
24673
24937
  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.`;
24674
24938
  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`).";
@@ -24728,6 +24992,7 @@ ${r.tasks.map(
24728
24992
  }
24729
24993
  case "call_agent": {
24730
24994
  const timeoutSec = Math.min(Math.max(Number(args2.timeout) || 180, 5), 300);
24995
+ await assertHostOwnsAgent(String(args2.target ?? ""));
24731
24996
  const created = await apiRequest("POST", "/tasks/assign", {
24732
24997
  assignee: args2.target,
24733
24998
  taskType: "rpc",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/mcp",
3
- "version": "0.9.5",
3
+ "version": "0.9.7",
4
4
  "mcpName": "io.github.agenticmail/mcp",
5
5
  "description": "MCP server for AgenticMail — give any AI client real email and SMS capabilities",
6
6
  "type": "module",