@essentialai/cogent-bridge 3.14.1 → 3.15.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cloud/mail-credential-store.d.ts +46 -0
  3. package/dist/cloud/mail-credential-store.d.ts.map +1 -0
  4. package/dist/cloud/mail-credential-store.js +80 -0
  5. package/dist/cloud/mail-credential-store.js.map +1 -0
  6. package/dist/index.js +6 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/mail/mail-fetcher.d.ts +112 -0
  9. package/dist/mail/mail-fetcher.d.ts.map +1 -0
  10. package/dist/mail/mail-fetcher.js +186 -0
  11. package/dist/mail/mail-fetcher.js.map +1 -0
  12. package/dist/mail/mail-sender.d.ts +64 -0
  13. package/dist/mail/mail-sender.d.ts.map +1 -0
  14. package/dist/mail/mail-sender.js +68 -0
  15. package/dist/mail/mail-sender.js.map +1 -0
  16. package/dist/mail/validate.d.ts +4 -0
  17. package/dist/mail/validate.d.ts.map +1 -0
  18. package/dist/mail/validate.js +16 -0
  19. package/dist/mail/validate.js.map +1 -0
  20. package/dist/tools/fetch-mail.d.ts +16 -0
  21. package/dist/tools/fetch-mail.d.ts.map +1 -0
  22. package/dist/tools/fetch-mail.js +55 -0
  23. package/dist/tools/fetch-mail.js.map +1 -0
  24. package/dist/tools/register-peer.d.ts.map +1 -1
  25. package/dist/tools/register-peer.js +13 -0
  26. package/dist/tools/register-peer.js.map +1 -1
  27. package/dist/tools/send-mail.d.ts +16 -0
  28. package/dist/tools/send-mail.d.ts.map +1 -0
  29. package/dist/tools/send-mail.js +49 -0
  30. package/dist/tools/send-mail.js.map +1 -0
  31. package/dist/tools/setup-mail.d.ts +10 -0
  32. package/dist/tools/setup-mail.d.ts.map +1 -0
  33. package/dist/tools/setup-mail.js +47 -0
  34. package/dist/tools/setup-mail.js.map +1 -0
  35. package/dist/types.d.ts +11 -0
  36. package/dist/types.d.ts.map +1 -1
  37. package/package.json +3 -1
  38. package/server.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.15.0 — 2026-08-08
4
+
5
+ ### Added — Cogent Mail: per-agent mailboxes + auto-provision (M2)
6
+ - **New agent tools**: `cogent_setup_mail` (store the mailbox address+password locally, 0600),
7
+ `cogent_send_mail` (SMTP submission with attachments read from local paths), and
8
+ `cogent_fetch_mail` (on-demand IMAP list/fetch; saves attachments by basename). Every mailbox
9
+ is `[agent]-[channel]@mail.cogent.tools` on the standalone Stalwart box.
10
+ - **Zero-touch provisioning for Team agents**: on a cloud Team `cogent_register_peer`, the relay
11
+ mints (or idempotently resolves) the peer's mailbox via the control plane and returns
12
+ `{address, password}` in the register response; the bridge saves it to its per-cwd 0600 store —
13
+ no manual `cogent_setup_mail` needed. `PeerInfo.mailbox` (response-only; password never stored
14
+ server-side).
15
+ - **A2A card autofill**: each peer's Agent Card advertises its mailbox address via a
16
+ `capabilities.extensions[]` entry (address only; the password never touches the card).
17
+ - Input hardening: `cogent_send_mail`/`cogent_setup_mail` validate the address shape before the
18
+ SMTP/credential sink. `nodemailer`/`imapflow` are lazy-imported (off the cold-start path).
19
+
3
20
  ## 3.14.1 — 2026-08-07
4
21
 
5
22
  ### Added — `cogent init` asks Local vs Cloud (writes the config; no hand-edit)
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Agent-owned local mailbox credentials (Cogent Mail M2). The mailbox password is a
3
+ * SECRET — the control plane hands it to the bridge ONCE (on provisioning/rotation)
4
+ * and never stores it, so the ONLY durable copy lives here, in an owner-only file.
5
+ * `cogent_send_mail` / `cogent_fetch_mail` read it; `cogent_rotate_mail_creds` updates it.
6
+ *
7
+ * Mirrors {@link ./credential-store} deliberately: a per-cwd file so project A's mailbox
8
+ * can't bleed into project B (the same isolation the cloud-credential store enforces).
9
+ */
10
+ export interface PersistedMailCredentials {
11
+ /** Full mailbox address `[peer]-[channel]@mail.cogent.tools`. */
12
+ address: string;
13
+ /** Mailbox password (SECRET) — used for SMTP submission + IMAP fetch. */
14
+ password: string;
15
+ imapHost: string;
16
+ imapPort: number;
17
+ smtpHost: string;
18
+ smtpPort: number;
19
+ savedAt: string;
20
+ }
21
+ /** The Cogent Mail box hostname — default IMAP/SMTP host for a mailbox (M2). */
22
+ export declare const MAIL_DEFAULT_HOST = "mail.cogent.tools";
23
+ /**
24
+ * Resolve the mailbox-credential path with the override hierarchy:
25
+ * 1. explicit `credentialPath` arg (tests, advanced users)
26
+ * 2. process.env.COGENT_MAIL_CREDENTIALS_FILE (operators with custom paths)
27
+ * 3. defaultMailCredentialPath(process.cwd()) (per-cwd, the default)
28
+ */
29
+ export declare function resolveMailCredentialPath(credentialPath?: string): string;
30
+ /** Load persisted mailbox credentials. Returns null on any error (absent / corrupt). */
31
+ export declare function loadMailCredentials(credentialPath?: string): Promise<PersistedMailCredentials | null>;
32
+ /** Save (upsert) mailbox credentials as 0600 JSON; creates the owner-only parent dir. */
33
+ export declare function saveMailCredentials(creds: PersistedMailCredentials, credentialPath?: string): Promise<void>;
34
+ /**
35
+ * Persist an auto-provisioned mailbox (Cogent Mail M2.7) with default hosts (IMAP 993 / SMTP 465
36
+ * on {@link MAIL_DEFAULT_HOST}). Returns true if it saved, false if there was nothing to save
37
+ * (no address, or no one-time password — e.g. a re-register that didn't re-issue the password).
38
+ * The caller uses this best-effort: a save failure must not break peer registration.
39
+ */
40
+ export declare function persistProvisionedMailbox(mailbox: {
41
+ address?: string;
42
+ password?: string;
43
+ } | undefined, credentialPath?: string): Promise<boolean>;
44
+ /** Delete the mailbox-credential file. Idempotent — a missing file is not an error. */
45
+ export declare function clearMailCredentials(credentialPath?: string): Promise<void>;
46
+ //# sourceMappingURL=mail-credential-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-credential-store.d.ts","sourceRoot":"","sources":["../../src/cloud/mail-credential-store.ts"],"names":[],"mappings":"AAKA;;;;;;;;GAQG;AACH,MAAM,WAAW,wBAAwB;IACvC,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,gFAAgF;AAChF,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AAYrD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAKzE;AAED,wFAAwF;AACxF,wBAAsB,mBAAmB,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAO3G;AAED,yFAAyF;AACzF,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOjH;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EAC5D,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC,CAelB;AAED,uFAAuF;AACvF,wBAAsB,oBAAoB,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOjF"}
@@ -0,0 +1,80 @@
1
+ import crypto from "node:crypto";
2
+ import fs from "node:fs/promises";
3
+ import path from "node:path";
4
+ import os from "node:os";
5
+ /** The Cogent Mail box hostname — default IMAP/SMTP host for a mailbox (M2). */
6
+ export const MAIL_DEFAULT_HOST = "mail.cogent.tools";
7
+ /**
8
+ * Per-cwd default location:
9
+ * ~/.cogent/mail-credentials/<sha256(absoluteCwd)[..16]>.json
10
+ * Each working directory (= one agent identity = one mailbox) gets its own file.
11
+ */
12
+ function defaultMailCredentialPath(cwd = process.cwd()) {
13
+ const hash = crypto.createHash("sha256").update(path.resolve(cwd)).digest("hex").slice(0, 16);
14
+ return path.join(os.homedir(), ".cogent", "mail-credentials", `${hash}.json`);
15
+ }
16
+ /**
17
+ * Resolve the mailbox-credential path with the override hierarchy:
18
+ * 1. explicit `credentialPath` arg (tests, advanced users)
19
+ * 2. process.env.COGENT_MAIL_CREDENTIALS_FILE (operators with custom paths)
20
+ * 3. defaultMailCredentialPath(process.cwd()) (per-cwd, the default)
21
+ */
22
+ export function resolveMailCredentialPath(credentialPath) {
23
+ if (credentialPath)
24
+ return credentialPath;
25
+ const envOverride = process.env.COGENT_MAIL_CREDENTIALS_FILE;
26
+ if (envOverride)
27
+ return envOverride;
28
+ return defaultMailCredentialPath();
29
+ }
30
+ /** Load persisted mailbox credentials. Returns null on any error (absent / corrupt). */
31
+ export async function loadMailCredentials(credentialPath) {
32
+ const filePath = resolveMailCredentialPath(credentialPath);
33
+ try {
34
+ return JSON.parse(await fs.readFile(filePath, "utf-8"));
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ }
40
+ /** Save (upsert) mailbox credentials as 0600 JSON; creates the owner-only parent dir. */
41
+ export async function saveMailCredentials(creds, credentialPath) {
42
+ const filePath = resolveMailCredentialPath(credentialPath);
43
+ // The password is a secret: owner-only dir + file. `mode` on mkdir/writeFile only
44
+ // applies on creation, so chmod afterward to also tighten a pre-existing file.
45
+ await fs.mkdir(path.dirname(filePath), { recursive: true, mode: 0o700 });
46
+ await fs.writeFile(filePath, JSON.stringify(creds, null, 2) + "\n", { encoding: "utf-8", mode: 0o600 });
47
+ await fs.chmod(filePath, 0o600);
48
+ }
49
+ /**
50
+ * Persist an auto-provisioned mailbox (Cogent Mail M2.7) with default hosts (IMAP 993 / SMTP 465
51
+ * on {@link MAIL_DEFAULT_HOST}). Returns true if it saved, false if there was nothing to save
52
+ * (no address, or no one-time password — e.g. a re-register that didn't re-issue the password).
53
+ * The caller uses this best-effort: a save failure must not break peer registration.
54
+ */
55
+ export async function persistProvisionedMailbox(mailbox, credentialPath) {
56
+ if (!mailbox?.address || !mailbox.password)
57
+ return false;
58
+ await saveMailCredentials({
59
+ address: mailbox.address,
60
+ password: mailbox.password,
61
+ imapHost: MAIL_DEFAULT_HOST,
62
+ imapPort: 993,
63
+ smtpHost: MAIL_DEFAULT_HOST,
64
+ smtpPort: 465,
65
+ savedAt: new Date().toISOString(),
66
+ }, credentialPath);
67
+ return true;
68
+ }
69
+ /** Delete the mailbox-credential file. Idempotent — a missing file is not an error. */
70
+ export async function clearMailCredentials(credentialPath) {
71
+ const filePath = resolveMailCredentialPath(credentialPath);
72
+ try {
73
+ await fs.unlink(filePath);
74
+ }
75
+ catch (err) {
76
+ if (err.code !== "ENOENT")
77
+ throw err;
78
+ }
79
+ }
80
+ //# sourceMappingURL=mail-credential-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-credential-store.js","sourceRoot":"","sources":["../../src/cloud/mail-credential-store.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -12,6 +12,9 @@ import { registerDeregisterPeerTool } from "./tools/deregister-peer.js";
12
12
  import { registerHealthCheckTool } from "./tools/health-check.js";
13
13
  import { registerCreateSessionTool } from "./tools/create-session.js";
14
14
  import { registerJoinSessionTool } from "./tools/join-session.js";
15
+ import { registerSetupMailTool } from "./tools/setup-mail.js";
16
+ import { registerSendMailTool } from "./tools/send-mail.js";
17
+ import { registerFetchMailTool } from "./tools/fetch-mail.js";
15
18
  import { heartbeat } from "./services/heartbeat.js";
16
19
  // ---------------------------------------------------------------------------
17
20
  // Global error handlers -- registered FIRST before anything else
@@ -70,6 +73,9 @@ async function main() {
70
73
  registerHealthCheckTool(server);
71
74
  registerCreateSessionTool(server);
72
75
  registerJoinSessionTool(server);
76
+ registerSetupMailTool(server);
77
+ registerSendMailTool(server);
78
+ registerFetchMailTool(server);
73
79
  // Register MCP inbox resource if cloud mode is active
74
80
  if (cloudInbox) {
75
81
  server.registerResource("cogent_inbox", "cogent://inbox", {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ import type { PersistedMailCredentials } from "../cloud/mail-credential-store.js";
2
+ /**
3
+ * Inbound-mail port (Cogent Mail M2.3). Symmetric to the outbound {@link MailSender}:
4
+ * the fetch tool depends on THIS interface, not on imapflow, so it is unit-testable with a
5
+ * fake IMAP session and the IMAP library is swappable + loaded lazily (off the cold-start
6
+ * path). Following RemoteDataSource / Dependency_Injection
7
+ * (typescript-master-vault/concepts/RemoteDataSource.md, Dependency_Injection.md).
8
+ */
9
+ export interface MailSummary {
10
+ uid: number;
11
+ from: string;
12
+ subject: string;
13
+ date: string;
14
+ unread: boolean;
15
+ }
16
+ export interface SavedAttachment {
17
+ filename: string;
18
+ savedPath: string;
19
+ size: number;
20
+ }
21
+ export interface FetchedMail {
22
+ uid: number;
23
+ from: string;
24
+ subject: string;
25
+ date: string;
26
+ text: string;
27
+ attachments: SavedAttachment[];
28
+ }
29
+ export interface MailFetcher {
30
+ /** List messages (most recent first) as lightweight summaries — no bodies downloaded. */
31
+ list(opts?: {
32
+ unreadOnly?: boolean;
33
+ limit?: number;
34
+ }): Promise<MailSummary[]>;
35
+ /** Fetch one message by UID: text body + attachments saved to `downloadDir`. */
36
+ fetchOne(uid: number, downloadDir: string): Promise<FetchedMail>;
37
+ }
38
+ /** Raw envelope row as produced by the IMAP session (already parsed to plain data). */
39
+ export interface RawMessage {
40
+ uid: number;
41
+ from: string;
42
+ subject: string;
43
+ date: string;
44
+ unread: boolean;
45
+ }
46
+ /** Decoded message content as produced by the IMAP session (attachments in memory). */
47
+ export interface RawContent {
48
+ from: string;
49
+ subject: string;
50
+ date: string;
51
+ text: string;
52
+ attachments: {
53
+ filename: string;
54
+ content: Buffer;
55
+ }[];
56
+ }
57
+ /**
58
+ * The minimal IMAP surface the fetcher needs. Returning already-parsed plain data keeps the
59
+ * imapflow specifics behind {@link defaultImapSessionFactory}, so ImapflowMailFetcher's
60
+ * disk-saving + summary logic is unit-tested against a fake session.
61
+ */
62
+ export interface ImapSession {
63
+ list(unreadOnly: boolean): Promise<RawMessage[]>;
64
+ fetch(uid: number): Promise<RawContent>;
65
+ close(): Promise<void>;
66
+ }
67
+ export type ImapSessionFactory = (creds: PersistedMailCredentials) => Promise<ImapSession>;
68
+ /** In-memory fetcher: a fixed inbox. The test double the tool drives. */
69
+ export declare class InMemoryMailFetcher implements MailFetcher {
70
+ private readonly inbox;
71
+ constructor(inbox?: (RawMessage & {
72
+ text: string;
73
+ attachments: {
74
+ filename: string;
75
+ content: Buffer;
76
+ }[];
77
+ })[]);
78
+ list(opts?: {
79
+ unreadOnly?: boolean;
80
+ limit?: number;
81
+ }): Promise<MailSummary[]>;
82
+ fetchOne(uid: number, downloadDir: string): Promise<FetchedMail>;
83
+ }
84
+ /**
85
+ * Real IMAP fetcher. The imapflow session is created LAZILY (dynamic import) so imapflow never
86
+ * loads on the cold-start path — only when the agent actually fetches mail. `sessionFactory` is
87
+ * the injection seam for tests (default connects a real imapflow session).
88
+ */
89
+ export declare class ImapflowMailFetcher implements MailFetcher {
90
+ private readonly creds;
91
+ private readonly sessionFactory;
92
+ constructor(creds: PersistedMailCredentials, sessionFactory?: ImapSessionFactory);
93
+ list(opts?: {
94
+ unreadOnly?: boolean;
95
+ limit?: number;
96
+ }): Promise<MailSummary[]>;
97
+ fetchOne(uid: number, downloadDir: string): Promise<FetchedMail>;
98
+ }
99
+ /** A leaf MIME part reference extracted from an imapflow bodyStructure tree. */
100
+ export interface MimePartRef {
101
+ part: string;
102
+ type: string;
103
+ isText: boolean;
104
+ filename?: string;
105
+ }
106
+ /**
107
+ * Flatten an imapflow bodyStructure into its leaf parts. Attachment leaves carry a `filename`
108
+ * (from disposition or content-type params); text/plain leaves are marked `isText`. Multipart
109
+ * container nodes (those with `childNodes`) are recursed, not emitted.
110
+ */
111
+ export declare function flattenBodyStructure(node: unknown, acc?: MimePartRef[]): MimePartRef[];
112
+ //# sourceMappingURL=mail-fetcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-fetcher.d.ts","sourceRoot":"","sources":["../../src/mail/mail-fetcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,186 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ /** In-memory fetcher: a fixed inbox. The test double the tool drives. */
4
+ export class InMemoryMailFetcher {
5
+ inbox;
6
+ constructor(inbox = []) {
7
+ this.inbox = inbox;
8
+ }
9
+ async list(opts = {}) {
10
+ let rows = this.inbox.map(({ uid, from, subject, date, unread }) => ({ uid, from, subject, date, unread }));
11
+ if (opts.unreadOnly)
12
+ rows = rows.filter((m) => m.unread);
13
+ if (opts.limit && opts.limit > 0)
14
+ rows = rows.slice(0, opts.limit);
15
+ return rows;
16
+ }
17
+ async fetchOne(uid, downloadDir) {
18
+ const msg = this.inbox.find((m) => m.uid === uid);
19
+ if (!msg)
20
+ throw new Error(`no message with uid ${uid}`);
21
+ const saved = await saveAttachments(msg.attachments, downloadDir);
22
+ return { uid, from: msg.from, subject: msg.subject, date: msg.date, text: msg.text, attachments: saved };
23
+ }
24
+ }
25
+ /**
26
+ * Real IMAP fetcher. The imapflow session is created LAZILY (dynamic import) so imapflow never
27
+ * loads on the cold-start path — only when the agent actually fetches mail. `sessionFactory` is
28
+ * the injection seam for tests (default connects a real imapflow session).
29
+ */
30
+ export class ImapflowMailFetcher {
31
+ creds;
32
+ sessionFactory;
33
+ constructor(creds, sessionFactory = defaultImapSessionFactory) {
34
+ this.creds = creds;
35
+ this.sessionFactory = sessionFactory;
36
+ }
37
+ async list(opts = {}) {
38
+ const session = await this.sessionFactory(this.creds);
39
+ try {
40
+ let rows = await session.list(opts.unreadOnly ?? false);
41
+ if (opts.limit && opts.limit > 0)
42
+ rows = rows.slice(0, opts.limit);
43
+ return rows;
44
+ }
45
+ finally {
46
+ await session.close();
47
+ }
48
+ }
49
+ async fetchOne(uid, downloadDir) {
50
+ const session = await this.sessionFactory(this.creds);
51
+ try {
52
+ const c = await session.fetch(uid);
53
+ const saved = await saveAttachments(c.attachments, downloadDir);
54
+ return { uid, from: c.from, subject: c.subject, date: c.date, text: c.text, attachments: saved };
55
+ }
56
+ finally {
57
+ await session.close();
58
+ }
59
+ }
60
+ }
61
+ /** Write each in-memory attachment to `downloadDir` (created if needed), named by basename. */
62
+ async function saveAttachments(attachments, downloadDir) {
63
+ if (attachments.length === 0)
64
+ return [];
65
+ await fs.mkdir(downloadDir, { recursive: true });
66
+ const saved = [];
67
+ for (const a of attachments) {
68
+ const name = path.basename(a.filename) || "attachment";
69
+ const savedPath = path.join(downloadDir, name);
70
+ await fs.writeFile(savedPath, a.content);
71
+ saved.push({ filename: name, savedPath, size: a.content.length });
72
+ }
73
+ return saved;
74
+ }
75
+ /**
76
+ * Default imapflow session. Lazily imported via a variable specifier so tsc/esbuild never
77
+ * statically resolve or bundle imapflow — it loads from node_modules only when an agent fetches
78
+ * mail (off the cold-start path). The imapflow call shapes here are verified against the real
79
+ * mail box at the M2.8 live A→B E2E (the same "wiring proven at live E2E" seam used by
80
+ * NodemailerMailSender.defaultTransport); the disk-save + summary logic around it is unit-tested.
81
+ */
82
+ async function defaultImapSessionFactory(creds) {
83
+ const specifier = "imapflow";
84
+ const { ImapFlow } = (await import(specifier));
85
+ const client = new ImapFlow({
86
+ host: creds.imapHost,
87
+ port: creds.imapPort,
88
+ secure: creds.imapPort === 993,
89
+ auth: { user: creds.address, pass: creds.password },
90
+ logger: false,
91
+ });
92
+ await client.connect();
93
+ await client.mailboxOpen("INBOX");
94
+ return {
95
+ async list(unreadOnly) {
96
+ const criteria = unreadOnly ? { seen: false } : { all: true };
97
+ const rows = [];
98
+ for await (const msg of client.fetch(criteria, { uid: true, envelope: true, flags: true })) {
99
+ const env = msg.envelope ?? {};
100
+ rows.push({
101
+ uid: msg.uid,
102
+ from: env.from?.[0]?.address ?? "",
103
+ subject: env.subject ?? "",
104
+ date: env.date instanceof Date ? env.date.toISOString() : String(env.date ?? ""),
105
+ unread: !hasFlag(msg.flags, "\\Seen"),
106
+ });
107
+ }
108
+ return rows.reverse(); // newest first
109
+ },
110
+ async fetch(uid) {
111
+ const msg = await client.fetchOne(uid, { uid: true, envelope: true, bodyStructure: true }, { uid: true });
112
+ if (!msg)
113
+ throw new Error(`no message with uid ${uid}`);
114
+ const parts = flattenBodyStructure(msg.bodyStructure);
115
+ let text = "";
116
+ const attachments = [];
117
+ for (const p of parts) {
118
+ if (p.filename) {
119
+ const dl = await client.download(uid, p.part, { uid: true });
120
+ attachments.push({ filename: p.filename, content: await streamToBuffer(dl.content) });
121
+ }
122
+ else if (p.isText && !text) {
123
+ const dl = await client.download(uid, p.part, { uid: true });
124
+ text = (await streamToBuffer(dl.content)).toString("utf-8");
125
+ }
126
+ }
127
+ const env = msg.envelope ?? {};
128
+ return {
129
+ from: env.from?.[0]?.address ?? "",
130
+ subject: env.subject ?? "",
131
+ date: env.date instanceof Date ? env.date.toISOString() : String(env.date ?? ""),
132
+ text,
133
+ attachments,
134
+ };
135
+ },
136
+ async close() {
137
+ try {
138
+ await client.logout();
139
+ }
140
+ catch {
141
+ /* best-effort close */
142
+ }
143
+ },
144
+ };
145
+ }
146
+ /**
147
+ * Flatten an imapflow bodyStructure into its leaf parts. Attachment leaves carry a `filename`
148
+ * (from disposition or content-type params); text/plain leaves are marked `isText`. Multipart
149
+ * container nodes (those with `childNodes`) are recursed, not emitted.
150
+ */
151
+ export function flattenBodyStructure(node, acc = []) {
152
+ if (!node || typeof node !== "object")
153
+ return acc;
154
+ const n = node;
155
+ if (Array.isArray(n.childNodes) && n.childNodes.length > 0) {
156
+ for (const child of n.childNodes)
157
+ flattenBodyStructure(child, acc);
158
+ return acc;
159
+ }
160
+ const type = (n.type ?? "").toLowerCase();
161
+ const filename = n.dispositionParameters?.filename ?? n.parameters?.name;
162
+ const isAttachment = (n.disposition ?? "").toLowerCase() === "attachment" || Boolean(filename);
163
+ acc.push({
164
+ part: n.part ?? "1", // single-part messages have no `part`; imapflow addresses them as "1"
165
+ type,
166
+ isText: type === "text/plain" && !isAttachment,
167
+ filename: isAttachment ? filename : undefined,
168
+ });
169
+ return acc;
170
+ }
171
+ function hasFlag(flags, flag) {
172
+ if (flags instanceof Set)
173
+ return flags.has(flag);
174
+ if (Array.isArray(flags))
175
+ return flags.includes(flag);
176
+ return false;
177
+ }
178
+ async function streamToBuffer(stream) {
179
+ const chunks = [];
180
+ if (!stream)
181
+ return Buffer.alloc(0);
182
+ for await (const chunk of stream)
183
+ chunks.push(Buffer.from(chunk));
184
+ return Buffer.concat(chunks);
185
+ }
186
+ //# sourceMappingURL=mail-fetcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-fetcher.js","sourceRoot":"","sources":["../../src/mail/mail-fetcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { PersistedMailCredentials } from "../cloud/mail-credential-store.js";
2
+ /**
3
+ * Outbound-mail port (Cogent Mail M2.2). Following RemoteDataSource / Dependency_Injection
4
+ * (typescript-master-vault/concepts/RemoteDataSource.md, Dependency_Injection.md): the send
5
+ * tool depends on THIS interface, not on nodemailer, so it is unit-testable with an in-memory
6
+ * double and the SMTP library is swappable + loaded lazily (off the cold-start path).
7
+ */
8
+ export interface OutgoingMail {
9
+ from: string;
10
+ to: string[];
11
+ subject: string;
12
+ text: string;
13
+ attachments: {
14
+ filename: string;
15
+ content: Buffer;
16
+ }[];
17
+ }
18
+ export interface MailSender {
19
+ send(mail: OutgoingMail): Promise<{
20
+ messageId: string;
21
+ }>;
22
+ }
23
+ /** In-memory sender: records what was sent. The test double the tool/service drives. */
24
+ export declare class InMemoryMailSender implements MailSender {
25
+ readonly sent: OutgoingMail[];
26
+ send(mail: OutgoingMail): Promise<{
27
+ messageId: string;
28
+ }>;
29
+ }
30
+ /**
31
+ * Real SMTP sender. nodemailer is imported LAZILY (dynamic import) so it never loads on
32
+ * the bridge's cold-start path — only when the agent actually sends mail. `transportFactory`
33
+ * is an injection seam for tests (default builds a real nodemailer SMTP transport from the creds).
34
+ */
35
+ export declare class NodemailerMailSender implements MailSender {
36
+ private readonly creds;
37
+ private readonly transportFactory?;
38
+ constructor(creds: PersistedMailCredentials, transportFactory?: (() => Promise<{
39
+ sendMail(opts: unknown): Promise<{
40
+ messageId?: string;
41
+ }>;
42
+ }>) | undefined);
43
+ send(mail: OutgoingMail): Promise<{
44
+ messageId: string;
45
+ }>;
46
+ private defaultTransport;
47
+ }
48
+ /**
49
+ * Compose and send a mail from the agent's mailbox: reads each attachment from its local path
50
+ * (streaming the bytes into a Buffer), builds the {@link OutgoingMail}, and sends via the port.
51
+ * A missing/unreadable attachment path fails loud (the caller surfaces it as errorResult) rather
52
+ * than silently dropping the file. Returns the message id + the sending address.
53
+ */
54
+ export declare function buildAndSendMail(sender: MailSender, creds: PersistedMailCredentials, params: {
55
+ to: string[];
56
+ subject: string;
57
+ text: string;
58
+ attachmentPaths?: string[];
59
+ }): Promise<{
60
+ messageId: string;
61
+ from: string;
62
+ to: string[];
63
+ }>;
64
+ //# sourceMappingURL=mail-sender.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-sender.d.ts","sourceRoot":"","sources":["../../src/mail/mail-sender.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAElF;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACtD;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D;AAED,wFAAwF;AACxF,qBAAa,kBAAmB,YAAW,UAAU;IACnD,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,CAAM;IAC7B,IAAI,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAI/D;AAED;;;;GAIG;AACH,qBAAa,oBAAqB,YAAW,UAAU;IAEnD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;gBADjB,KAAK,EAAE,wBAAwB,EAC/B,gBAAgB,CAAC,GAAE,MAAM,OAAO,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;YAAE,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,aAAA;IAG3G,IAAI,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;YAYhD,gBAAgB;CAY/B;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,wBAAwB,EAC/B,MAAM,EAAE;IAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAClF,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAc5D"}
@@ -0,0 +1,68 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ /** In-memory sender: records what was sent. The test double the tool/service drives. */
4
+ export class InMemoryMailSender {
5
+ sent = [];
6
+ async send(mail) {
7
+ this.sent.push(mail);
8
+ return { messageId: `inmem-${this.sent.length}` };
9
+ }
10
+ }
11
+ /**
12
+ * Real SMTP sender. nodemailer is imported LAZILY (dynamic import) so it never loads on
13
+ * the bridge's cold-start path — only when the agent actually sends mail. `transportFactory`
14
+ * is an injection seam for tests (default builds a real nodemailer SMTP transport from the creds).
15
+ */
16
+ export class NodemailerMailSender {
17
+ creds;
18
+ transportFactory;
19
+ constructor(creds, transportFactory) {
20
+ this.creds = creds;
21
+ this.transportFactory = transportFactory;
22
+ }
23
+ async send(mail) {
24
+ const transport = this.transportFactory ? await this.transportFactory() : await this.defaultTransport();
25
+ const info = await transport.sendMail({
26
+ from: mail.from,
27
+ to: mail.to,
28
+ subject: mail.subject,
29
+ text: mail.text,
30
+ attachments: mail.attachments.map((a) => ({ filename: a.filename, content: a.content })),
31
+ });
32
+ return { messageId: info.messageId ?? "" };
33
+ }
34
+ async defaultTransport() {
35
+ // Variable specifier so tsc/esbuild don't statically resolve+bundle nodemailer — it loads
36
+ // lazily from node_modules only when an agent actually sends mail (off the cold-start path).
37
+ const specifier = "nodemailer";
38
+ const nodemailer = (await import(specifier));
39
+ return nodemailer.createTransport({
40
+ host: this.creds.smtpHost,
41
+ port: this.creds.smtpPort,
42
+ secure: this.creds.smtpPort === 465, // implicit TLS on 465, STARTTLS on 587
43
+ auth: { user: this.creds.address, pass: this.creds.password },
44
+ });
45
+ }
46
+ }
47
+ /**
48
+ * Compose and send a mail from the agent's mailbox: reads each attachment from its local path
49
+ * (streaming the bytes into a Buffer), builds the {@link OutgoingMail}, and sends via the port.
50
+ * A missing/unreadable attachment path fails loud (the caller surfaces it as errorResult) rather
51
+ * than silently dropping the file. Returns the message id + the sending address.
52
+ */
53
+ export async function buildAndSendMail(sender, creds, params) {
54
+ const attachments = [];
55
+ for (const p of params.attachmentPaths ?? []) {
56
+ const content = await fs.readFile(p); // throws (ENOENT/EACCES) → fail loud, not a silent drop
57
+ attachments.push({ filename: path.basename(p), content });
58
+ }
59
+ const { messageId } = await sender.send({
60
+ from: creds.address,
61
+ to: params.to,
62
+ subject: params.subject,
63
+ text: params.text,
64
+ attachments,
65
+ });
66
+ return { messageId, from: creds.address, to: params.to };
67
+ }
68
+ //# sourceMappingURL=mail-sender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-sender.js","sourceRoot":"","sources":["../../src/mail/mail-sender.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAqB7B,wFAAwF;AACxF,MAAM,OAAO,kBAAkB;IACpB,IAAI,GAAmB,EAAE,CAAC;IACnC,KAAK,CAAC,IAAI,CAAC,IAAkB;QAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,OAAO,EAAE,SAAS,EAAE,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;IACpD,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,OAAO,oBAAoB;IAEZ;IACA;IAFnB,YACmB,KAA+B,EAC/B,gBAA8F;QAD9F,UAAK,GAAL,KAAK,CAA0B;QAC/B,qBAAgB,GAAhB,gBAAgB,CAA8E;IAC9G,CAAC;IAEJ,KAAK,CAAC,IAAI,CAAC,IAAkB;QAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxG,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC;YACpC,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;SACzF,CAAC,CAAC;QACH,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;IAC7C,CAAC;IAEO,KAAK,CAAC,gBAAgB;QAC5B,0FAA0F;QAC1F,6FAA6F;QAC7F,MAAM,SAAS,GAAG,YAAY,CAAC;QAC/B,MAAM,UAAU,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,CAAgD,CAAC;QAC5F,OAAO,UAAU,CAAC,eAAe,CAAC;YAChC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ;YACzB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ;YACzB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,KAAK,GAAG,EAAE,uCAAuC;YAC5E,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;SAC9D,CAA4E,CAAC;IAChF,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAkB,EAClB,KAA+B,EAC/B,MAAmF;IAEnF,MAAM,WAAW,GAA4C,EAAE,CAAC;IAChE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,eAAe,IAAI,EAAE,EAAE,CAAC;QAC7C,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,wDAAwD;QAC9F,WAAW,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC;QACtC,IAAI,EAAE,KAAK,CAAC,OAAO;QACnB,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,WAAW;KACZ,CAAC,CAAC;IACH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function isValidEmail(value: string): boolean;
2
+ /** Throw a BridgeError(INVALID_INPUT) unless `value` is a plausibly-valid email address. */
3
+ export declare function assertValidEmail(value: string, field: string): void;
4
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/mail/validate.ts"],"names":[],"mappings":"AAQA,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAQnE"}
@@ -0,0 +1,16 @@
1
+ import { BridgeError, BridgeErrorCode } from "../errors.js";
2
+ // Deliberately conservative: one @, non-empty local + domain, a dot in the domain, no
3
+ // whitespace. Not RFC-5322-exhaustive — enough to reject fat-finger input and give a clear
4
+ // error at the tool boundary before it reaches the SMTP recipient / credential file, rather
5
+ // than surfacing a cryptic SMTP/IMAP failure later.
6
+ const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
7
+ export function isValidEmail(value) {
8
+ return value.length <= 254 && EMAIL_RE.test(value);
9
+ }
10
+ /** Throw a BridgeError(INVALID_INPUT) unless `value` is a plausibly-valid email address. */
11
+ export function assertValidEmail(value, field) {
12
+ if (!isValidEmail(value)) {
13
+ throw new BridgeError(BridgeErrorCode.INVALID_INPUT, `${field} is not a valid email address: ${JSON.stringify(value)}`, `Provide a full address like agent-channel@mail.cogent.tools`);
14
+ }
15
+ }
16
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/mail/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE5D,sFAAsF;AACtF,2FAA2F;AAC3F,4FAA4F;AAC5F,oDAAoD;AACpD,MAAM,QAAQ,GAAG,4BAA4B,CAAC;AAE9C,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO,KAAK,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACrD,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,KAAa;IAC3D,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,WAAW,CACnB,eAAe,CAAC,aAAa,EAC7B,GAAG,KAAK,kCAAkC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EACjE,6DAA6D,CAC9D,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type PersistedMailCredentials } from "../cloud/mail-credential-store.js";
3
+ import { type MailFetcher } from "../mail/mail-fetcher.js";
4
+ /** Injection seam for tests: how a {@link MailFetcher} is built from the loaded creds. */
5
+ export interface FetchMailDeps {
6
+ fetcherFactory?: (creds: PersistedMailCredentials) => MailFetcher;
7
+ }
8
+ /**
9
+ * cogent_fetch_mail — read this agent's own mailbox (Cogent Mail M2.3). Two actions:
10
+ * - "list" (default): lightweight envelope summaries (uid/from/subject/date/unread), no bodies.
11
+ * - "fetch": download one message by uid — text body + attachments saved to a local dir.
12
+ * On-demand only (no background polling — Hybrid C). imapflow loads lazily off the cold path.
13
+ * `deps.fetcherFactory` lets tests drive a fake IMAP inbox instead of a real server.
14
+ */
15
+ export declare function registerFetchMailTool(server: McpServer, deps?: FetchMailDeps): void;
16
+ //# sourceMappingURL=fetch-mail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-mail.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-mail.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,EAAuB,KAAK,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AACvG,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAKhF,0FAA0F;AAC1F,MAAM,WAAW,aAAa;IAC5B,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,WAAW,CAAC;CACnE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,GAAE,aAAkB,GAAG,IAAI,CAqDvF"}
@@ -0,0 +1,55 @@
1
+ import os from "node:os";
2
+ import path from "node:path";
3
+ import { z } from "zod";
4
+ import { BridgeError, BridgeErrorCode, successResult, errorResult } from "../errors.js";
5
+ import { loadMailCredentials } from "../cloud/mail-credential-store.js";
6
+ import { ImapflowMailFetcher } from "../mail/mail-fetcher.js";
7
+ /** Where fetched attachments land by default (per-agent download dir). */
8
+ const DEFAULT_DOWNLOAD_DIR = path.join(os.homedir(), ".cogent", "mail-downloads");
9
+ /**
10
+ * cogent_fetch_mail — read this agent's own mailbox (Cogent Mail M2.3). Two actions:
11
+ * - "list" (default): lightweight envelope summaries (uid/from/subject/date/unread), no bodies.
12
+ * - "fetch": download one message by uid — text body + attachments saved to a local dir.
13
+ * On-demand only (no background polling — Hybrid C). imapflow loads lazily off the cold path.
14
+ * `deps.fetcherFactory` lets tests drive a fake IMAP inbox instead of a real server.
15
+ */
16
+ export function registerFetchMailTool(server, deps = {}) {
17
+ const makeFetcher = deps.fetcherFactory ?? ((creds) => new ImapflowMailFetcher(creds));
18
+ server.registerTool("cogent_fetch_mail", {
19
+ title: "Read this agent's mailbox",
20
+ description: "List messages in this agent's Cogent mailbox, or fetch one message (text + attachments " +
21
+ "saved locally) by uid. Requires cogent_setup_mail to have stored the mailbox credentials.",
22
+ inputSchema: {
23
+ action: z.enum(["list", "fetch"]).optional().describe("'list' (default) or 'fetch' one message"),
24
+ uid: z.number().int().positive().optional().describe("Message uid to fetch (required when action='fetch')"),
25
+ unreadOnly: z.boolean().optional().describe("List only unread messages (default false)"),
26
+ limit: z.number().int().positive().optional().describe("Max messages to list (default 25)"),
27
+ downloadDir: z
28
+ .string()
29
+ .optional()
30
+ .describe(`Directory to save fetched attachments (default ${DEFAULT_DOWNLOAD_DIR})`),
31
+ },
32
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
33
+ }, async ({ action, uid, unreadOnly, limit, downloadDir }) => {
34
+ try {
35
+ const creds = await loadMailCredentials();
36
+ if (!creds) {
37
+ return errorResult(new BridgeError(BridgeErrorCode.INVALID_INPUT, "No mailbox is configured for this agent", "Run cogent_setup_mail with the address + password from the admin Mail panel first"));
38
+ }
39
+ const fetcher = makeFetcher(creds);
40
+ if (action === "fetch") {
41
+ if (uid === undefined) {
42
+ return errorResult(new BridgeError(BridgeErrorCode.INVALID_INPUT, "uid is required when action='fetch'", "Pass the uid from a cogent_fetch_mail list"));
43
+ }
44
+ const message = await fetcher.fetchOne(uid, downloadDir ?? DEFAULT_DOWNLOAD_DIR);
45
+ return successResult({ mailbox: creds.address, message });
46
+ }
47
+ const messages = await fetcher.list({ unreadOnly, limit: limit ?? 25 });
48
+ return successResult({ mailbox: creds.address, count: messages.length, messages });
49
+ }
50
+ catch (err) {
51
+ return errorResult(err);
52
+ }
53
+ });
54
+ }
55
+ //# sourceMappingURL=fetch-mail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-mail.js","sourceRoot":"","sources":["../../src/tools/fetch-mail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,mBAAmB,EAAiC,MAAM,mCAAmC,CAAC;AACvG,OAAO,EAAE,mBAAmB,EAAoB,MAAM,yBAAyB,CAAC;AAEhF,0EAA0E;AAC1E,MAAM,oBAAoB,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC;AAOlF;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAiB,EAAE,OAAsB,EAAE;IAC/E,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,IAAI,CAAC,CAAC,KAA+B,EAAE,EAAE,CAAC,IAAI,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;IAEjH,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,2BAA2B;QAClC,WAAW,EACT,yFAAyF;YACzF,2FAA2F;QAC7F,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;YAChG,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qDAAqD,CAAC;YAC3G,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;YACxF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YAC3F,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,kDAAkD,oBAAoB,GAAG,CAAC;SACvF;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;KACvG,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE;QACxD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,mBAAmB,EAAE,CAAC;YAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,WAAW,CAChB,IAAI,WAAW,CACb,eAAe,CAAC,aAAa,EAC7B,yCAAyC,EACzC,mFAAmF,CACpF,CACF,CAAC;YACJ,CAAC;YACD,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;YAEnC,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBACvB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;oBACtB,OAAO,WAAW,CAChB,IAAI,WAAW,CAAC,eAAe,CAAC,aAAa,EAAE,qCAAqC,EAAE,4CAA4C,CAAC,CACpI,CAAC;gBACJ,CAAC;gBACD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,IAAI,oBAAoB,CAAC,CAAC;gBACjF,OAAO,aAAa,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC;YACxE,OAAO,aAAa,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"register-peer.d.ts","sourceRoot":"","sources":["../../src/tools/register-peer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAmBpE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwWhE"}
1
+ {"version":3,"file":"register-peer.d.ts","sourceRoot":"","sources":["../../src/tools/register-peer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAoBpE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsXhE"}
@@ -4,6 +4,7 @@ import { getConfig } from "../config.js";
4
4
  import { getBackend, isCloudEndpoint, isCloudMode } from "../backend/index.js";
5
5
  import { successResult, errorResult, BridgeError, BridgeErrorCode } from "../errors.js";
6
6
  import { saveCredentials, loadCredentials, hasJoinedInProcess, hasCloudAttemptInProcess, } from "../cloud/credential-store.js";
7
+ import { persistProvisionedMailbox } from "../cloud/mail-credential-store.js";
7
8
  import { logger } from "../logger.js";
8
9
  import { heartbeat } from "../services/heartbeat.js";
9
10
  import { autoRelay } from "../services/auto-relay.js";
@@ -195,6 +196,18 @@ export function registerRegisterPeerTool(server) {
195
196
  logger.debug(`check-on-stop: could not stamp peerId into credentials: ${err.message}`);
196
197
  }
197
198
  }
199
+ // Cogent Mail M2.7: if the relay auto-provisioned a mailbox for this peer (Team channel),
200
+ // persist the one-time credentials to the local 0600 mail store so cogent_send_mail /
201
+ // cogent_fetch_mail can use them without a manual cogent_setup_mail. Best-effort — a failure
202
+ // must never break registration — and the password value is never logged.
203
+ try {
204
+ if (await persistProvisionedMailbox(peer?.mailbox)) {
205
+ logger.info(`Cogent Mail: saved auto-provisioned mailbox ${peer.mailbox?.address}`);
206
+ }
207
+ }
208
+ catch (err) {
209
+ logger.warn(`Cogent Mail: could not save auto-provisioned mailbox creds: ${err.message}`);
210
+ }
198
211
  // Set local peer info for auto-relay (cloud mode: incoming messages trigger local execClaude).
199
212
  // Auto-detect the real local CC session ID from the filesystem — the user/agent may
200
213
  // pass the cloud session ID by mistake, which won't work with `claude --resume`.
@@ -1 +1 @@
1
- {"version":3,"file":"register-peer.js","sourceRoot":"","sources":["../../src/tools/register-peer.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,EACL,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAE9D,MAAM,UAAU,wBAAwB,CAAC,MAAiB;IACxD,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,gEAAgE;YAChE,+DAA+D;YAC/D,0DAA0D;QAC5D,WAAW,EAAE;YACX,MAAM,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,QAAQ,CAAC,+DAA+D,CAAC;YAC5E,SAAS,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,CAAC,6CAA6C,CAAC;YAC1D,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,QAAQ,CAAC,gDAAgD,CAAC;YAC7D,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,CAAC,kEAAkE,CAAC;YAC/E,IAAI,EAAE,CAAC;iBACJ,IAAI,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;iBAC3B,QAAQ,EAAE;iBACV,OAAO,CAAC,OAAO,CAAC;iBAChB,QAAQ,CACP,0GAA0G;gBAC1G,yHAAyH;gBACzH,qHAAqH,CACtH;YACH,IAAI,EAAE,CAAC;iBACJ,IAAI,CAAC,CAAC,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;iBAC3D,QAAQ,EAAE;iBACV,QAAQ,CACP,6FAA6F;gBAC7F,oHAAoH;gBACpH,4GAA4G,CAC7G;SACJ;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;QACtD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAE3B,mFAAmF;YACnF,gFAAgF;YAChF,mFAAmF;YACnF,gFAAgF;YAChF,2EAA2E;YAC3E,kFAAkF;YAClF,mFAAmF;YACnF,MAAM,uBAAuB,GAC3B,CAAC,CAAC,MAAM,CAAC,iBAAiB;gBAC1B,OAAO,CAAC,GAAG,CAAC,kCAAkC,KAAK,GAAG,CAAC;YACzD,IACE,CAAC,uBAAuB;gBACxB,wBAAwB,EAAE;gBAC1B,CAAC,kBAAkB,EAAE,EACrB,CAAC;gBACD,OAAO,WAAW,CAChB,IAAI,WAAW,CACb,eAAe,CAAC,kBAAkB,EAClC,mQAAmQ,EACnQ,mKAAmK,CACpK,CACF,CAAC;YACJ,CAAC;YAED,+DAA+D;YAC/D,uDAAuD;YACvD,MAAM,sBAAsB,GAC1B,MAAM,CAAC,eAAe;gBACtB,eAAe,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;YAE1C,qDAAqD;YACrD,IAAI,cAAc,GAAG,KAAK,CAAC;YAC3B,IAAI,cAAkC,CAAC;YACvC,IAAI,UAA8B,CAAC;YAEnC,IAAI,sBAAsB,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;gBACrD,IAAI,QAAQ,GAAG,MAAM,CAAC,eAAe,CAAC;gBAEtC,kEAAkE;gBAClE,cAAc,GAAG,MAAM,CAAC,iBAAiB,CAAC;gBAC1C,IAAI,UAA8B,CAAC;gBAEnC,IAAI,CAAC,cAAc,EAAE,CAAC;oBACpB,qEAAqE;oBACrE,sEAAsE;oBACtE,yEAAyE;oBACzE,gEAAgE;oBAChE,MAAM,cAAc,GAClB,kBAAkB,EAAE;wBACpB,OAAO,CAAC,GAAG,CAAC,kCAAkC,KAAK,GAAG,CAAC;oBACzD,IAAI,cAAc,EAAE,CAAC;wBACnB,MAAM,SAAS,GAAG,MAAM,eAAe,EAAE,CAAC;wBAC1C,yEAAyE;wBACzE,iFAAiF;wBACjF,iFAAiF;wBACjF,8EAA8E;wBAC9E,iFAAiF;wBACjF,IACE,SAAS;4BACT,CAAC,SAAS,CAAC,QAAQ,KAAK,MAAM,CAAC,eAAe;gCAC5C,SAAS,CAAC,QAAQ,KAAK,MAAM,CAAC,oBAAoB,CAAC,EACrD,CAAC;4BACD,cAAc,GAAG,SAAS,CAAC,SAAS,CAAC;4BACrC,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC;4BAC7B,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC;wBAChC,CAAC;oBACH,CAAC;gBACH,CAAC;gBAED,IAAI,CAAC,cAAc,EAAE,CAAC;oBACpB,oDAAoD;oBACpD,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;oBACpD,MAAM,IAAI,GAAG,MAAM,KAAK,CACtB,GAAG,QAAQ,eAAe,EAC1B;wBACE,MAAM,EAAE,MAAM;wBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;wBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;4BACnB,MAAM,EAAE,UAAU;4BAClB,KAAK,EAAE,mBAAmB,KAAK,EAAE;yBAClC,CAAC;qBACH,CACF,CAAC;oBAEF,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;wBACb,OAAO,WAAW,CAChB,IAAI,KAAK,CACP,uCAAuC,IAAI,CAAC,MAAM,EAAE,CACrD,CACF,CAAC;oBACJ,CAAC;oBAED,MAAM,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAIjC,CAAC;oBACF,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC;oBACnC,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC;oBAC3B,cAAc,GAAG,IAAI,CAAC;oBAEtB,yEAAyE;oBACzE,MAAM,eAAe,CAAC;wBACpB,QAAQ;wBACR,SAAS,EAAE,cAAc;wBACzB,KAAK,EAAE,UAAU;wBACjB,MAAM;wBACN,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;qBAClC,CAAC,CAAC;oBAEH,4CAA4C;oBAC5C,+DAA+D;oBAC/D,IAAI,CAAC;wBACH,MAAM,aAAa,GAAG,CAAC,MAAM,MAAM,CACjC,eAAe,CAChB,CAA4B,CAAC;wBAC9B,IACE,OAAO,aAAa,CAAC,kBAAkB,KAAK,UAAU,EACtD,CAAC;4BACD,MACE,aAAa,CAAC,kBAKf,CAAC,QAAQ,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;wBAC1C,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,uCAAuC;oBACzC,CAAC;oBAED,MAAM,CAAC,IAAI,CACT,8BAA8B,cAAc,EAAE,CAC/C,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,+DAA+D;YAC/D,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC/C,qEAAqE;YACrE,uCAAuC;YACvC,sEAAsE;YACtE,qEAAqE;YACrE,iEAAiE;YACjE,wEAAwE;YACxE,+DAA+D;YAC/D,0EAA0E;YAC1E,oEAAoE;YACpE,iEAAiE;YACjE,MAAM,gBAAgB,GAAG,SAAS,CAAC;YACnC,MAAM,YAAY,GAChB,IAAI,KAAK,UAAU;gBACjB,CAAC,CAAC,CAAC,UAAU,CAAC;gBACd,CAAC,CAAC,CAAC,aAAa,EAAE,qCAAqC,CAAC,CAAC;YAC7D,wEAAwE;YACxE,wEAAwE;YACxE,IAAI,IAAI,EAAE,CAAC;gBACT,YAAY,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;YACpC,CAAC;YACD,yEAAyE;YACzE,uEAAuE;YACvE,2EAA2E;YAC3E,2EAA2E;YAC3E,6DAA6D;YAC7D,MAAM,WAAW,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;YAC3C,MAAM,QAAQ,GAAG,SAAS,CAAC;YAC3B,gEAAgE;YAChE,oEAAoE;YACpE,mEAAmE;YACnE,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,YAAY,CACrC,MAAM,EACN,SAAS,EACT,GAAG,EACH,KAAK,EACL,cAAc,EACd,IAAI,EACJ,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,QAAQ,CACT,CAAC;YAEF,2EAA2E;YAC3E,0EAA0E;YAC1E,0EAA0E;YAC1E,kEAAkE;YAClE,IAAI,WAAW,EAAE,EAAE,CAAC;gBAClB,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAC;oBACtC,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;wBACrC,MAAM,eAAe,CAAC;4BACpB,GAAG,KAAK;4BACR,MAAM;4BACN,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;yBAClC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,KAAK,CACV,2DAA4D,GAAa,CAAC,OAAO,EAAE,CACpF,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,+FAA+F;YAC/F,oFAAoF;YACpF,iFAAiF;YACjF,qEAAqE;YACrE,kEAAkE;YAClE,wEAAwE;YACxE,4CAA4C;YAC5C,MAAM,UAAU,GAAG,MAAM,cAAc,CACrC,SAAS,EAAE,CAAC,eAAe,EAC3B,GAAG,EACH,SAAS,CACV,CAAC;YACF,MAAM,cAAc,GAAG,UAAU,CAAC,SAAS,IAAI,SAAS,CAAC;YACzD,MAAM,CAAC,IAAI,CACT,8BAA8B,UAAU,CAAC,QAAQ,IAAI,UAAU,CAAC,UAAU,GAAG;gBAC3E,IAAI,UAAU,CAAC,cAAc,qBAAqB,cAAc,EAAE,CACrE,CAAC;YACF,qEAAqE;YACrE,wCAAwC;YACxC,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;YAEjF,iEAAiE;YACjE,MAAM,MAAM,GAA4B;gBACtC,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY;gBAC3C,IAAI;gBACJ,iBAAiB,EAAE;oBACjB,QAAQ,EAAE,UAAU,CAAC,QAAQ;oBAC7B,UAAU,EAAE,UAAU,CAAC,UAAU;oBACjC,cAAc,EAAE,UAAU,CAAC,cAAc;iBAC1C;aACF,CAAC;YAEF,0EAA0E;YAC1E,oFAAoF;YACpF,iFAAiF;YACjF,gFAAgF;YAChF,iFAAiF;YACjF,MAAM,aAAa,GAAI,IAAsC,EAAE,QAAQ,CAAC;YACxE,MAAM,WAAW,GACf,CAAC,OAAO,aAAa,KAAK,QAAQ,IAAI,aAAa,CAAC,IAAI,YAAY,EAAE,CAAC;YACzE,IAAI,WAAW;gBAAE,MAAM,CAAC,eAAe,GAAG,WAAW,CAAC;YAEtD,IAAI,cAAc,IAAI,cAAc,IAAI,UAAU,EAAE,CAAC;gBACnD,MAAM,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC9B,MAAM,CAAC,WAAW,GAAG;oBACnB,SAAS,EAAE,cAAc;oBACzB,MAAM,EAAE,UAAU;iBACnB,CAAC;gBACF,MAAM,EAAE,GAAG,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC;gBACxC,MAAM,CAAC,cAAc,GAAG;oBACtB,QAAQ,EACN,mBAAmB,EAAE,IAAI;wBACzB,qBAAqB,cAAc,IAAI;wBACvC,iBAAiB,UAAU,EAAE;oBAC/B,UAAU,EAAE;wBACV,QAAQ,EAAE;4BACR,OAAO,EAAE,KAAK;4BACd,IAAI,EAAE,CAAC,4BAA4B,CAAC;4BACpC,GAAG,EAAE;gCACH,eAAe,EAAE,EAAE;gCACnB,iBAAiB,EAAE,cAAc;gCACjC,aAAa,EAAE,UAAU;6BAC1B;yBACF;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,sEAAsE;YACtE,wEAAwE;YACxE,4EAA4E;YAC5E,IAAI,WAAW,EAAE,EAAE,CAAC;gBAClB,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;oBAC9C,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;wBAC1B,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;wBACxC,4FAA4F;wBAC5F,MAAM,CAAC,IAAI,CAAC,2CAA2C,MAAM,EAAE,CAAC,CAAC;oBACnE,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,wDAAwD;oBACxD,MAAM,CAAC,IAAI,CAAC,2CAA2C,GAAG,EAAE,CAAC,CAAC;gBAChE,CAAC;YACH,CAAC;YAED,sDAAsD;YACtD,oEAAoE;YACpE,kEAAkE;YAClE,IAAI,OAAiC,CAAC;YACtC,IAAI,CAAC;gBACH,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;gBACjD,OAAO,GAAG,UAAU,CAAC,qBAAqB,CAAC;YAC7C,CAAC;YAAC,MAAM,CAAC;gBACP,gDAAgD;YAClD,CAAC;YACD,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;YAEzC,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YACrD,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"register-peer.js","sourceRoot":"","sources":["../../src/tools/register-peer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type PersistedMailCredentials } from "../cloud/mail-credential-store.js";
3
+ import { type MailSender } from "../mail/mail-sender.js";
4
+ /** Injection seam for tests: how a {@link MailSender} is built from the loaded creds. */
5
+ export interface SendMailDeps {
6
+ senderFactory?: (creds: PersistedMailCredentials) => MailSender;
7
+ }
8
+ /**
9
+ * cogent_send_mail — send an email from this agent's mailbox (Cogent Mail M2.2). Reads the
10
+ * agent's own creds from the local store, composes the message with optional attachments read
11
+ * from local file paths, and submits over SMTP (as the agent — no admin). The heavy SMTP lib
12
+ * loads lazily only when this runs. Thin glue over buildAndSendMail (unit-tested in mail-sender.test).
13
+ * `deps.senderFactory` lets tests drive an in-memory sender instead of real SMTP.
14
+ */
15
+ export declare function registerSendMailTool(server: McpServer, deps?: SendMailDeps): void;
16
+ //# sourceMappingURL=send-mail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send-mail.d.ts","sourceRoot":"","sources":["../../src/tools/send-mail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,EAAuB,KAAK,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AACvG,OAAO,EAA0C,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGjG,yFAAyF;AACzF,MAAM,WAAW,YAAY;IAC3B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,UAAU,CAAC;CACjE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,GAAE,YAAiB,GAAG,IAAI,CA6CrF"}
@@ -0,0 +1,49 @@
1
+ import { z } from "zod";
2
+ import { BridgeError, BridgeErrorCode, successResult, errorResult } from "../errors.js";
3
+ import { loadMailCredentials } from "../cloud/mail-credential-store.js";
4
+ import { NodemailerMailSender, buildAndSendMail } from "../mail/mail-sender.js";
5
+ import { assertValidEmail } from "../mail/validate.js";
6
+ /**
7
+ * cogent_send_mail — send an email from this agent's mailbox (Cogent Mail M2.2). Reads the
8
+ * agent's own creds from the local store, composes the message with optional attachments read
9
+ * from local file paths, and submits over SMTP (as the agent — no admin). The heavy SMTP lib
10
+ * loads lazily only when this runs. Thin glue over buildAndSendMail (unit-tested in mail-sender.test).
11
+ * `deps.senderFactory` lets tests drive an in-memory sender instead of real SMTP.
12
+ */
13
+ export function registerSendMailTool(server, deps = {}) {
14
+ const makeSender = deps.senderFactory ?? ((creds) => new NodemailerMailSender(creds));
15
+ server.registerTool("cogent_send_mail", {
16
+ title: "Send an email from this agent's mailbox",
17
+ description: "Send an email (with optional file attachments) from this agent's Cogent mailbox to another " +
18
+ "address. Requires cogent_setup_mail to have stored the mailbox credentials first.",
19
+ inputSchema: {
20
+ to: z.string().describe("Recipient email address, e.g. other-agent-backend@mail.cogent.tools"),
21
+ subject: z.string().describe("Email subject"),
22
+ body: z.string().describe("Plain-text email body"),
23
+ attachments: z
24
+ .array(z.string())
25
+ .optional()
26
+ .describe("Optional local file paths to attach (each is read and attached by basename)"),
27
+ },
28
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
29
+ }, async ({ to, subject, body, attachments }) => {
30
+ try {
31
+ assertValidEmail(to, "to"); // fail fast at the tool boundary, before the SMTP sink
32
+ const creds = await loadMailCredentials();
33
+ if (!creds) {
34
+ return errorResult(new BridgeError(BridgeErrorCode.INVALID_INPUT, "No mailbox is configured for this agent", "Run cogent_setup_mail with the address + password from the admin Mail panel first"));
35
+ }
36
+ const result = await buildAndSendMail(makeSender(creds), creds, {
37
+ to: [to],
38
+ subject,
39
+ text: body,
40
+ attachmentPaths: attachments,
41
+ });
42
+ return successResult({ ...result, attachmentCount: attachments?.length ?? 0 });
43
+ }
44
+ catch (err) {
45
+ return errorResult(err);
46
+ }
47
+ });
48
+ }
49
+ //# sourceMappingURL=send-mail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send-mail.js","sourceRoot":"","sources":["../../src/tools/send-mail.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,mBAAmB,EAAiC,MAAM,mCAAmC,CAAC;AACvG,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAmB,MAAM,wBAAwB,CAAC;AACjG,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAOvD;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAiB,EAAE,OAAqB,EAAE;IAC7E,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC,KAA+B,EAAE,EAAE,CAAC,IAAI,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC;IAChH,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;QACE,KAAK,EAAE,yCAAyC;QAChD,WAAW,EACT,6FAA6F;YAC7F,mFAAmF;QACrF,WAAW,EAAE;YACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qEAAqE,CAAC;YAC9F,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;YAC7C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;YAClD,WAAW,EAAE,CAAC;iBACX,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBACjB,QAAQ,EAAE;iBACV,QAAQ,CAAC,6EAA6E,CAAC;SAC3F;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;KACzG,EACD,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE;QAC3C,IAAI,CAAC;YACH,gBAAgB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,uDAAuD;YACnF,MAAM,KAAK,GAAG,MAAM,mBAAmB,EAAE,CAAC;YAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,WAAW,CAChB,IAAI,WAAW,CACb,eAAe,CAAC,aAAa,EAC7B,yCAAyC,EACzC,mFAAmF,CACpF,CACF,CAAC;YACJ,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE;gBAC9D,EAAE,EAAE,CAAC,EAAE,CAAC;gBACR,OAAO;gBACP,IAAI,EAAE,IAAI;gBACV,eAAe,EAAE,WAAW;aAC7B,CAAC,CAAC;YACH,OAAO,aAAa,CAAC,EAAE,GAAG,MAAM,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC,CAAC;QACjF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ /**
3
+ * cogent_setup_mail — store this agent's mailbox credentials locally (Cogent Mail M2).
4
+ * The operator provisions the mailbox in the admin Mail panel (M1), which shows the
5
+ * address + password ONCE; the agent runs this tool to save them to its per-cwd 0600
6
+ * store so cogent_send_mail / cogent_fetch_mail can use them. (Auto-provision on register
7
+ * is a deferred follow-up — see the M2.7 design note.)
8
+ */
9
+ export declare function registerSetupMailTool(server: McpServer): void;
10
+ //# sourceMappingURL=setup-mail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-mail.d.ts","sourceRoot":"","sources":["../../src/tools/setup-mail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAqC7D"}
@@ -0,0 +1,47 @@
1
+ import { z } from "zod";
2
+ import { successResult, errorResult } from "../errors.js";
3
+ import { saveMailCredentials, MAIL_DEFAULT_HOST } from "../cloud/mail-credential-store.js";
4
+ import { assertValidEmail } from "../mail/validate.js";
5
+ const DEFAULT_MAIL_HOST = MAIL_DEFAULT_HOST;
6
+ /**
7
+ * cogent_setup_mail — store this agent's mailbox credentials locally (Cogent Mail M2).
8
+ * The operator provisions the mailbox in the admin Mail panel (M1), which shows the
9
+ * address + password ONCE; the agent runs this tool to save them to its per-cwd 0600
10
+ * store so cogent_send_mail / cogent_fetch_mail can use them. (Auto-provision on register
11
+ * is a deferred follow-up — see the M2.7 design note.)
12
+ */
13
+ export function registerSetupMailTool(server) {
14
+ server.registerTool("cogent_setup_mail", {
15
+ title: "Configure this agent's mailbox",
16
+ description: "Store the agent's mailbox address + password (from the admin Mail panel) locally so " +
17
+ "cogent_send_mail and cogent_fetch_mail can use them. Hosts default to mail.cogent.tools " +
18
+ "(IMAP 993 / SMTP 465).",
19
+ inputSchema: {
20
+ address: z.string().describe("Full mailbox address, e.g. claude-agent-backend@mail.cogent.tools"),
21
+ password: z.string().describe("Mailbox password (shown once in the admin Mail panel on create/rotate)"),
22
+ imapHost: z.string().optional().describe(`IMAP host (default ${DEFAULT_MAIL_HOST})`),
23
+ imapPort: z.number().int().positive().optional().describe("IMAP port (default 993)"),
24
+ smtpHost: z.string().optional().describe(`SMTP host (default ${DEFAULT_MAIL_HOST})`),
25
+ smtpPort: z.number().int().positive().optional().describe("SMTP submission port (default 465)"),
26
+ },
27
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
28
+ }, async ({ address, password, imapHost, imapPort, smtpHost, smtpPort }) => {
29
+ try {
30
+ assertValidEmail(address, "address"); // reject fat-finger creds before persisting
31
+ await saveMailCredentials({
32
+ address,
33
+ password,
34
+ imapHost: imapHost ?? DEFAULT_MAIL_HOST,
35
+ imapPort: imapPort ?? 993,
36
+ smtpHost: smtpHost ?? DEFAULT_MAIL_HOST,
37
+ smtpPort: smtpPort ?? 465,
38
+ savedAt: new Date().toISOString(),
39
+ });
40
+ return successResult({ configured: true, address });
41
+ }
42
+ catch (err) {
43
+ return errorResult(err);
44
+ }
45
+ });
46
+ }
47
+ //# sourceMappingURL=setup-mail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-mail.js","sourceRoot":"","sources":["../../src/tools/setup-mail.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC3F,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACrD,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,gCAAgC;QACvC,WAAW,EACT,sFAAsF;YACtF,0FAA0F;YAC1F,wBAAwB;QAC1B,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mEAAmE,CAAC;YACjG,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wEAAwE,CAAC;YACvG,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,iBAAiB,GAAG,CAAC;YACpF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;YACpF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,iBAAiB,GAAG,CAAC;YACpF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;SAChG;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE;KACzG,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE;QACtE,IAAI,CAAC;YACH,gBAAgB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,4CAA4C;YAClF,MAAM,mBAAmB,CAAC;gBACxB,OAAO;gBACP,QAAQ;gBACR,QAAQ,EAAE,QAAQ,IAAI,iBAAiB;gBACvC,QAAQ,EAAE,QAAQ,IAAI,GAAG;gBACzB,QAAQ,EAAE,QAAQ,IAAI,iBAAiB;gBACvC,QAAQ,EAAE,QAAQ,IAAI,GAAG;gBACzB,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aAClC,CAAC,CAAC;YACH,OAAO,aAAa,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
package/dist/types.d.ts CHANGED
@@ -39,6 +39,17 @@ export interface PeerInfo {
39
39
  workspaceId?: string;
40
40
  /** Durable thread/conversation identifier (Slice 5 / Story 8.6). On the wire; optional. */
41
41
  threadId?: string;
42
+ /**
43
+ * Cogent Mail auto-provisioned mailbox (M2.7). Present ONLY on a cloud register RESPONSE
44
+ * for a Team channel where the relay minted (or resolved) this peer's mailbox via the
45
+ * control-plane provisioner. `password` is returned ONCE (on first create / explicit rotate)
46
+ * and is never persisted server-side — the bridge saves it to its local 0600 store and drops
47
+ * it. Absent on free channels and on re-registers that don't re-issue a password.
48
+ */
49
+ mailbox?: {
50
+ address: string;
51
+ password?: string;
52
+ };
42
53
  }
43
54
  export interface MessageRecord {
44
55
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,sFAAsF;IACtF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;OAUG;IACH,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IAC5B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,IAAI,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;CAC7D;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,cAAc,GAAG,eAAe,CAAC;IACnD,2DAA2D;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,sFAAsF;IACtF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;OAUG;IACH,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IAC5B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAClD;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,IAAI,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;CAC7D;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,cAAc,GAAG,eAAe,CAAC;IACnD,2DAA2D;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@essentialai/cogent-bridge",
3
- "version": "3.14.1",
3
+ "version": "3.15.0",
4
4
  "description": "MCP server for inter-Claude-Code session communication bridge",
5
5
  "type": "module",
6
6
  "workspaces": [
@@ -66,6 +66,8 @@
66
66
  "dependencies": {
67
67
  "@essentialai/cogent": "^3.6.0",
68
68
  "@modelcontextprotocol/sdk": "^1.6.1",
69
+ "imapflow": "^1.6.6",
70
+ "nodemailer": "^6.10.1",
69
71
  "ws": "^8.19.0",
70
72
  "zod": "^3.23.8"
71
73
  },
package/server.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "name": "io.github.eaisdevelopment/cogent",
4
4
  "title": "Cogent Bridge from Essential AI Solutions (essentialai.uk)",
5
5
  "description": "MCP bridge for inter-session communication between Claude Code instances",
6
- "version": "3.14.1",
6
+ "version": "3.15.0",
7
7
  "repository": {
8
8
  "url": "https://github.com/eaisdevelopment/cogent",
9
9
  "source": "github"
@@ -12,7 +12,7 @@
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "@essentialai/cogent-bridge",
15
- "version": "3.14.1",
15
+ "version": "3.15.0",
16
16
  "runtimeHint": "npx",
17
17
  "transport": {
18
18
  "type": "stdio"