proton-mail-bridge-client 2.7.2 → 2.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +66 -2
- package/dist/index.js.map +1 -1
- package/dist/scripts/setup-claude-desktop.d.ts +12 -0
- package/dist/scripts/setup-claude-desktop.d.ts.map +1 -1
- package/dist/scripts/setup-claude-desktop.js +43 -2
- package/dist/scripts/setup-claude-desktop.js.map +1 -1
- package/dist/services/delivery-queue-service.d.ts.map +1 -1
- package/dist/services/delivery-queue-service.js +7 -6
- package/dist/services/delivery-queue-service.js.map +1 -1
- package/dist/services/draft-store-service.d.ts.map +1 -1
- package/dist/services/draft-store-service.js +10 -9
- package/dist/services/draft-store-service.js.map +1 -1
- package/dist/services/local-index-service.d.ts.map +1 -1
- package/dist/services/local-index-service.js +6 -6
- package/dist/services/local-index-service.js.map +1 -1
- package/dist/services/simple-imap-service.d.ts +2 -0
- package/dist/services/simple-imap-service.d.ts.map +1 -1
- package/dist/services/simple-imap-service.js +33 -12
- package/dist/services/simple-imap-service.js.map +1 -1
- package/dist/services/snooze-service.d.ts.map +1 -1
- package/dist/services/snooze-service.js +5 -4
- package/dist/services/snooze-service.js.map +1 -1
- package/dist/services/template-service.d.ts.map +1 -1
- package/dist/services/template-service.js +3 -2
- package/dist/services/template-service.js.map +1 -1
- package/dist/utils/helpers.d.ts +1 -0
- package/dist/utils/helpers.d.ts.map +1 -1
- package/dist/utils/helpers.js +59 -13
- package/dist/utils/helpers.js.map +1 -1
- package/dist/utils/own-record.d.ts +2 -0
- package/dist/utils/own-record.d.ts.map +1 -0
- package/dist/utils/own-record.js +6 -0
- package/dist/utils/own-record.js.map +1 -0
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { AccountManager, type AccountBundle } from "./services/account-manager.j
|
|
|
10
10
|
export declare const CORE_TOOL_NAMES: Set<string>;
|
|
11
11
|
export declare function withSources<T>(value: T, _sources: CitationSource[]): T;
|
|
12
12
|
export declare function withAudit<T>(auditService: AuditService, tool: string, input: Record<string, unknown>, operation: () => Promise<T>): Promise<T>;
|
|
13
|
+
export declare function ignoredArguments(toolName: string, args: unknown): string[];
|
|
13
14
|
export declare function optionalClearableString(args: Record<string, unknown>, key: string): string | undefined;
|
|
14
15
|
export declare function headerString(headers: Record<string, unknown> | undefined, name: string): string | undefined;
|
|
15
16
|
export declare function parseAuthenticationResults(value?: string): {
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AASA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAYnE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAuD,MAAM,mCAAmC,CAAC;AAC3H,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAA2H,iBAAiB,EAA+B,MAAM,mCAAmC,CAAC;AAC5N,OAAO,EAAmC,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC1F,OAAO,KAAK,EAMV,mBAAmB,EACnB,cAAc,EACd,WAAW,EAIX,WAAW,EAIX,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AASA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAYnE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAuD,MAAM,mCAAmC,CAAC;AAC3H,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAA2H,iBAAiB,EAA+B,MAAM,mCAAmC,CAAC;AAC5N,OAAO,EAAmC,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC1F,OAAO,KAAK,EAMV,mBAAmB,EACnB,cAAc,EACd,WAAW,EAIX,WAAW,EAIX,gBAAgB,EAEhB,cAAc,EAGf,MAAM,kBAAkB,CAAC;AA2B1B,OAAO,EAAE,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,+BAA+B,CAAC;AA2uDnF,eAAO,MAAM,eAAe,aA2C1B,CAAC;AAqCH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,CAAC,CAEtE;AAqGD,wBAAsB,SAAS,CAAC,CAAC,EAC/B,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAC1B,OAAO,CAAC,CAAC,CAAC,CAmCZ;AAmDD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,EAAE,CAO1E;AAsDD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKtG;AA+CD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAK3G;AAKD,wBAAgB,0BAA0B,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAI1G;AASD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAa9E;AAMD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAmBtH;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,WAAW,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAW1I;AA8ID,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMrD;AAKD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAW3D;AAeD,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAWxE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAiB3E;AAaD,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAW5E;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAe/E;AAWD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,OAAO,EACjB,kBAAkB,GAAE,MAAM,EAAO,GAChC;IAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IAAC,EAAE,EAAE,MAAM,EAAE,CAAA;CAAE,CA+BhC;AA6ED,wBAAgB,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CA4CtE;AAcD,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYlE;AAsBD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAQ/F;AAED,wBAAgB,4BAA4B,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,KAAK,EAAE,CAAC,KAUhF;AAQD,wBAAgB,4BAA4B,CAAC,CAAC,SAAS;IAAE,OAAO,EAAE,cAAc,CAAA;CAAE,EAAE,MAAM,EAAE,CAAC,KA8B5F;AA+JD,wBAAsB,4BAA4B,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8CrH;AAoKD,eAAO,MAAM,iCAAiC,QAAS,CAAC;AAExD,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,OAAO,EAAE,CAAC,EAAE,EACZ,WAAW,SAAoC,GAC9C;IAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAYnC;AAYD,wBAAsB,6BAA6B,CACjD,WAAW,EAAE,IAAI,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,EACtD,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,sBAAsB,CAAC,EAClE,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC,CAgBlB;AAgID,wBAAgB,4BAA4B,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAKjI;AAgQD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAEzE;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAOzE;AAED,UAAU,mBAAmB;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AASD,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAS,EAC9B,MAAM,EAAE,MAAM,EACd,kBAAkB,CAAC,EAAE,MAAM,GAC1B,mBAAmB,EAAE,CA8CvB;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,mBAAmB,EAC3B,gBAAgB,EAAE,mBAAmB,EAAE,GACtC,mBAAmB,CAmBrB;AAWD,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,MAAM,EAAE,GACjB,GAAG,CAAC,MAAM,GAAG,SAAS,EAAE;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAYvE;AAOD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,mBAAmB,CAQ3G;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,mBAAmB,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,mBAAmB,EAAE,CAK/G;AAID,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,mBAAmB,CASpF;AAsQD,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,cAGC;CACF;AAED,wBAAgB,kBAAkB,IAAI,gBAAgB,CAkGrD;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE;IACP,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmpJP;AAOD,wBAAsB,eAAe,CACnC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,uBAAuB,GAAG,sBAAsB,GAAG,eAAe,GAAG,aAAa,GAAG,aAAa,GAAG,mBAAmB,CAAC,CAAC,EAC7J,SAAS,SAAQ,GAChB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,eAAO,MAAM,sBAAsB,QAGiG,CAAC;AAIrI,wBAAgB,wBAAwB,IAAI,MAAM,CAQjD;AAaD,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAyE1C"}
|
package/dist/index.js
CHANGED
|
@@ -1853,6 +1853,8 @@ const AUDIT_MAX_DEPTH = 8;
|
|
|
1853
1853
|
const AUDIT_REDACTED_KEYS = new Set([
|
|
1854
1854
|
"body", "html", "text", "htmlBody", "textBody", "markdownBody", "customMessage", "notes", "bodyEdits",
|
|
1855
1855
|
"raw", "rawBase64", "base64", "content", "find", "replace", "signature",
|
|
1856
|
+
// Parts of a received message that a tool result could carry: a preview or attachment text can hold a code or a secret.
|
|
1857
|
+
"preview", "snippet", "attachmentText", "latestPreview",
|
|
1856
1858
|
]);
|
|
1857
1859
|
const AUDIT_SECRET_KEY = /pass(word|wd|phrase)?$|secret|token|api[-_]?key|authoriz|credential|cookie|private[-_]?key/i;
|
|
1858
1860
|
function sanitizeAuditValue(value, depth = 0, seen = new WeakSet()) {
|
|
@@ -1963,6 +1965,58 @@ function parseBodyEdits(value) {
|
|
|
1963
1965
|
return { find: edit.find, replace: edit.replace, ...(edit.all === true ? { all: true } : {}) };
|
|
1964
1966
|
});
|
|
1965
1967
|
}
|
|
1968
|
+
// Moving a message into the Trash folder is trashing it: trash_email is literally a move there. The move tools
|
|
1969
|
+
// therefore need the "trash" permission as well as "move" when the destination is the Trash folder, or an
|
|
1970
|
+
// ALLOWED_ACTIONS list that leaves out "trash" could be sidestepped by moving to Trash instead.
|
|
1971
|
+
async function ensureMoveTargetAllowed(runtime, imap, targetFolder) {
|
|
1972
|
+
if (!targetFolder)
|
|
1973
|
+
return;
|
|
1974
|
+
// A call that can span accounts is checked against every account's own Trash folder: their names may differ.
|
|
1975
|
+
let unknown = false;
|
|
1976
|
+
for (const candidate of Array.isArray(imap) ? imap : [imap]) {
|
|
1977
|
+
const isTrash = await candidate.isTrashFolder(targetFolder);
|
|
1978
|
+
if (isTrash) {
|
|
1979
|
+
ensureEmailActionAllowed(runtime, "trash");
|
|
1980
|
+
return;
|
|
1981
|
+
}
|
|
1982
|
+
if (isTrash === undefined)
|
|
1983
|
+
unknown = true;
|
|
1984
|
+
}
|
|
1985
|
+
// Not being able to tell must not open a way round the permission: with "trash" not allowed, refuse.
|
|
1986
|
+
if (unknown && !runtime.allowedActions.includes("trash")) {
|
|
1987
|
+
throw new McpError(ErrorCode.InternalError, `Cannot tell whether ${targetFolder} is the Trash folder (the folder list could not be read), and the trash action is not allowed. Try again when Bridge answers.`);
|
|
1988
|
+
}
|
|
1989
|
+
}
|
|
1990
|
+
// Arguments a tool does not declare are ignored (clients send extra fields, and refusing them would break
|
|
1991
|
+
// those clients), but silently: `folder` on get_threads did nothing for a long time and nobody was told. The
|
|
1992
|
+
// result now carries a note naming them, so the caller (usually a model) learns the argument had no effect.
|
|
1993
|
+
export function ignoredArguments(toolName, args) {
|
|
1994
|
+
const tool = TOOLS.find((candidate) => candidate.name === toolName);
|
|
1995
|
+
if (!tool || !args || typeof args !== "object" || Array.isArray(args)) {
|
|
1996
|
+
return [];
|
|
1997
|
+
}
|
|
1998
|
+
const declared = new Set(Object.keys(tool.inputSchema.properties ?? {}));
|
|
1999
|
+
return Object.keys(args).filter((key) => !declared.has(key));
|
|
2000
|
+
}
|
|
2001
|
+
function withIgnoredArgumentsNote(handler) {
|
|
2002
|
+
return async (request) => {
|
|
2003
|
+
const result = await handler(request);
|
|
2004
|
+
const ignored = ignoredArguments(request.params.name, request.params.arguments);
|
|
2005
|
+
if (ignored.length === 0) {
|
|
2006
|
+
return result;
|
|
2007
|
+
}
|
|
2008
|
+
// The names come from the caller; keep the note short however many or however long they are.
|
|
2009
|
+
const shown = ignored.slice(0, 10).map((key) => `"${key.length > 64 ? `${key.slice(0, 64)}...` : key}"`);
|
|
2010
|
+
if (ignored.length > shown.length)
|
|
2011
|
+
shown.push(`and ${ignored.length - shown.length} more`);
|
|
2012
|
+
logger.warn("Tool call had arguments the tool does not accept", "MCPServer", { name: request.params.name, ignored: shown });
|
|
2013
|
+
const tool = TOOLS.find((candidate) => candidate.name === request.params.name);
|
|
2014
|
+
const accepted = Object.keys(tool?.inputSchema?.properties ?? {});
|
|
2015
|
+
const note = `Note: ${request.params.name} does not accept ${shown.join(", ")}; ignored. ` +
|
|
2016
|
+
(accepted.length > 0 ? `It accepts: ${accepted.join(", ")}.` : "It takes no arguments.");
|
|
2017
|
+
return { ...result, content: [...result.content, { type: "text", text: note }] };
|
|
2018
|
+
};
|
|
2019
|
+
}
|
|
1966
2020
|
function asObject(value) {
|
|
1967
2021
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1968
2022
|
return {};
|
|
@@ -3980,7 +4034,7 @@ export function createServer(config, options = {}) {
|
|
|
3980
4034
|
}
|
|
3981
4035
|
}
|
|
3982
4036
|
});
|
|
3983
|
-
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
4037
|
+
server.setRequestHandler(CallToolRequestSchema, withIgnoredArgumentsNote(async (request) => {
|
|
3984
4038
|
const name = request.params.name;
|
|
3985
4039
|
const args = asObject(request.params.arguments);
|
|
3986
4040
|
logger.debug("Handling tool call", "MCPServer", { name, argKeys: Object.keys(args || {}) });
|
|
@@ -5610,6 +5664,7 @@ export function createServer(config, options = {}) {
|
|
|
5610
5664
|
throw new McpError(ErrorCode.InvalidParams, "Provide emailIds OR match, not both.");
|
|
5611
5665
|
const folder = optionalString(args, "folder") ?? "INBOX";
|
|
5612
5666
|
const targetFolder = requireString(args, "targetFolder");
|
|
5667
|
+
await ensureMoveTargetAllowed(config.runtime, accountManager.all().map((entry) => entry.imapService), targetFolder);
|
|
5613
5668
|
const max = getBulkMaxBatchSize(args);
|
|
5614
5669
|
const dryRun = normalizeBoolean(args.dryRun, false);
|
|
5615
5670
|
// emailIds can span multiple configured accounts (a "<slug>::"
|
|
@@ -5927,6 +5982,7 @@ export function createServer(config, options = {}) {
|
|
|
5927
5982
|
// (e.g. a match/threading key that could resolve differently per
|
|
5928
5983
|
// account) is out of scope for this pass.
|
|
5929
5984
|
const { bundle, rest: messageId } = resolveAccountForEmailId(requireString(args, "messageId"));
|
|
5985
|
+
await ensureMoveTargetAllowed(config.runtime, bundle.imapService, requireString(args, "destination"));
|
|
5930
5986
|
const result = await withAudit(bundle.auditService, name, args, () => bundle.imapService.moveThread({
|
|
5931
5987
|
messageId,
|
|
5932
5988
|
destination: requireString(args, "destination"),
|
|
@@ -6055,6 +6111,7 @@ export function createServer(config, options = {}) {
|
|
|
6055
6111
|
const rawEmailId = requireString(args, "emailId");
|
|
6056
6112
|
const { bundle, rest: emailId } = resolveAccountForEmailId(rawEmailId);
|
|
6057
6113
|
const targetFolder = requireString(args, "targetFolder");
|
|
6114
|
+
await ensureMoveTargetAllowed(config.runtime, bundle.imapService, targetFolder);
|
|
6058
6115
|
const uidValidity = parseEmailId(emailId).uidValidity;
|
|
6059
6116
|
const result = await withAudit(auditService, name, args, async () => {
|
|
6060
6117
|
try {
|
|
@@ -6128,6 +6185,7 @@ export function createServer(config, options = {}) {
|
|
|
6128
6185
|
ensureEmailActionAllowed(config.runtime, "restore");
|
|
6129
6186
|
const rawEmailId = requireString(args, "emailId");
|
|
6130
6187
|
const { bundle, rest: emailId } = resolveAccountForEmailId(rawEmailId);
|
|
6188
|
+
await ensureMoveTargetAllowed(config.runtime, bundle.imapService, optionalString(args, "targetFolder"));
|
|
6131
6189
|
const uidValidity = parseEmailId(emailId).uidValidity;
|
|
6132
6190
|
const result = await withAudit(auditService, name, args, async () => bundle.imapService.restoreEmail(emailId, optionalString(args, "targetFolder"), uidValidity));
|
|
6133
6191
|
const targetEmailId = result.targetEmailId ? prefixedIdFor(bundle, result.targetEmailId) : undefined;
|
|
@@ -6276,6 +6334,9 @@ export function createServer(config, options = {}) {
|
|
|
6276
6334
|
const continueOnError = normalizeBoolean(args.continueOnError, true);
|
|
6277
6335
|
const dryRun = normalizeBoolean(args.dryRun, false);
|
|
6278
6336
|
const targetFolder = optionalString(args, "targetFolder");
|
|
6337
|
+
if (action === "move" || action === "restore") {
|
|
6338
|
+
await ensureMoveTargetAllowed(config.runtime, accountManager.all().map((entry) => entry.imapService), targetFolder);
|
|
6339
|
+
}
|
|
6279
6340
|
const groups = groupEmailIdsByAccount(accountManager, emailIds);
|
|
6280
6341
|
const groupResults = [];
|
|
6281
6342
|
for (const [slug, group] of groups) {
|
|
@@ -7433,6 +7494,9 @@ export function createServer(config, options = {}) {
|
|
|
7433
7494
|
const thread = await bundle.localIndexService.getThreadById(threadId);
|
|
7434
7495
|
const action = requireEmailAction(args);
|
|
7435
7496
|
ensureEmailActionAllowed(config.runtime, action);
|
|
7497
|
+
if (action === "move" || action === "restore") {
|
|
7498
|
+
await ensureMoveTargetAllowed(config.runtime, bundle.imapService, optionalString(args, "targetFolder"));
|
|
7499
|
+
}
|
|
7436
7500
|
const unreadOnly = normalizeBoolean(args.unreadOnly, false);
|
|
7437
7501
|
const emailIds = [...new Set(thread.messages
|
|
7438
7502
|
.filter((message) => !unreadOnly || !message.isRead)
|
|
@@ -7674,7 +7738,7 @@ export function createServer(config, options = {}) {
|
|
|
7674
7738
|
?? "An internal error occurred. Check get_logs for details, or run run_doctor for a full connectivity check.";
|
|
7675
7739
|
throw new McpError(ErrorCode.InternalError, message);
|
|
7676
7740
|
}
|
|
7677
|
-
});
|
|
7741
|
+
}));
|
|
7678
7742
|
return {
|
|
7679
7743
|
server,
|
|
7680
7744
|
smtpService,
|