@redpop/apple-mail-actions-mcp 0.0.0-stage → 0.3.2

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.
@@ -0,0 +1,131 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { HelperError } from '@redpop/apple-mail-mcp/dist/errors.js';
3
+ import { computePolicy } from '@redpop/apple-mail-mcp/dist/policy.js';
4
+ import { listMailboxesResult, probeResult } from '@redpop/apple-mail-mcp/dist/schemas.js';
5
+ import { readBundleId } from '@redpop/apple-mail-mcp/dist/signing.js';
6
+ import { ADHOC_BUNDLE_ID, checkActionsBundle, DEV_BUNDLE_ID, RELEASE_BUNDLE_ID } from '../bundle.js';
7
+ import { ActionsError, describeActionsError } from '../errors.js';
8
+ import { unsupportedAccountReason } from '../rules.js';
9
+ const REASON_TEXT = {
10
+ type: 'not an IMAP account',
11
+ allmail: 'has an "All Mail" folder',
12
+ gmail: 'Gmail accounts are not supported',
13
+ name_missing: 'Mail does not report a usable account name',
14
+ name_duplicate: 'another account has the same name',
15
+ };
16
+ /** Systemaufruf als ExecFn des Bundle-Gatters: Fehlschlag wirft. */
17
+ function throwing(exec) {
18
+ return (file, args) => {
19
+ const r = exec(file, args);
20
+ if (r.status !== 0)
21
+ throw new Error('exec failed');
22
+ return r.stdout;
23
+ };
24
+ }
25
+ /** true: Spalte fehlt, false: vorhanden, null: unbekannt. Quelle sind `missing` und die CREATE-Zeilen der Probe. */
26
+ function headerColumnMissing(schema) {
27
+ if (schema.missing.some((m) => m.includes('message_id_header')))
28
+ return true;
29
+ const table = (schema.ddl ?? []).find((d) => /CREATE\s+TABLE\s+(IF NOT EXISTS\s+)?"?message_global_data"?(?!\w)/i.test(d));
30
+ if (table === undefined)
31
+ return null;
32
+ return !table.includes('message_id_header');
33
+ }
34
+ export async function runActionsDoctor(deps) {
35
+ const checks = [];
36
+ const add = (id, status, message) => void checks.push({ id, status, message });
37
+ const readExit = await deps.readDoctor();
38
+ // Bundle und Signatur
39
+ const override = deps.override;
40
+ let bundleFine = false;
41
+ try {
42
+ checkActionsBundle(deps.bundlePath, { override, exec: throwing(deps.exec), exists: deps.exists ?? existsSync });
43
+ bundleFine = true;
44
+ let id = 'unknown';
45
+ try {
46
+ id = readBundleId(deps.bundlePath, throwing(deps.exec));
47
+ }
48
+ catch {
49
+ // Das Gatter hat die ID schon gelesen.
50
+ }
51
+ const kind = id === RELEASE_BUNDLE_ID ? 'release' : id === DEV_BUNDLE_ID ? 'development' : id === ADHOC_BUNDLE_ID ? 'ad hoc' : 'unknown';
52
+ add('actions-bundle', kind === 'ad hoc' ? 'warn' : 'ok', `Actions bundle found, ${kind} signature, identifier ${id}.`);
53
+ }
54
+ catch (e) {
55
+ add('actions-bundle', 'fail', e instanceof ActionsError ? describeActionsError(e.code) : 'The Actions bundle could not be checked.');
56
+ }
57
+ // Automation-Freigabe (nie ein Dialog: nur `permission`)
58
+ if (bundleFine) {
59
+ try {
60
+ const status = (await deps.actions.run('permission', {}))?.status;
61
+ if (status === 'granted')
62
+ add('automation', 'ok', 'Mail MCP Actions may control Mail.');
63
+ else if (status === 'mail_not_running')
64
+ add('automation', 'warn', 'Unknown because Mail is not running. Open Mail and run doctor again.');
65
+ else if (status === 'denied')
66
+ add('automation', 'fail', 'Denied. Switch on Mail under "Mail MCP Actions" in System Settings > Privacy & Security > Automation.');
67
+ else if (status === 'undetermined')
68
+ add('automation', 'warn', 'Not asked yet. Run `setup` with Mail open.');
69
+ else
70
+ add('automation', 'fail', 'The Actions app gave an unexpected answer.');
71
+ }
72
+ catch (e) {
73
+ add('automation', 'fail', e instanceof ActionsError ? describeActionsError(e.code) : e instanceof HelperError && e.code === 'MAIL_NOT_RUNNING' ? 'Unknown because Mail is not running.' : describeActionsError('ACTIONS_UNAVAILABLE'));
74
+ }
75
+ }
76
+ // Konfiguration
77
+ const cfg = deps.configResult;
78
+ if (!cfg.ok && cfg.key === 'APPLE_MAIL_ACCOUNTS') {
79
+ add('accounts-config', 'warn', 'APPLE_MAIL_ACCOUNTS is not set. The server refuses to move messages without it; set it to the accounts it may touch.');
80
+ }
81
+ else if (!cfg.ok) {
82
+ add('accounts-config', 'fail', `Configuration error in ${cfg.key}: ${cfg.error}`);
83
+ }
84
+ else {
85
+ add('accounts-config', 'ok', `APPLE_MAIL_ACCOUNTS names ${cfg.config.accounts.length} entr${cfg.config.accounts.length === 1 ? 'y' : 'ies'}; at most ${cfg.config.maxMoves} moves per call.`);
86
+ }
87
+ // Helper-Abfragen: Kopfspalte und Konten
88
+ let probe = null;
89
+ try {
90
+ probe = probeResult.parse(await deps.helper.run('probe', {}));
91
+ }
92
+ catch {
93
+ probe = null;
94
+ }
95
+ if (probe?.access === 'granted' && probe.schema) {
96
+ const missing = headerColumnMissing(probe.schema);
97
+ if (missing === true)
98
+ add('message-id-header', 'warn', 'Mail has no message_id_header column on this Mac (macOS 15): the tool cannot move mail on this Mac.');
99
+ else if (missing === null)
100
+ add('message-id-header', 'warn', 'Whether the message_id_header column exists could not be determined.');
101
+ else
102
+ add('message-id-header', 'ok', 'The message_id_header column exists.');
103
+ if (deps.baseConfig === null) {
104
+ add('accounts', 'warn', 'Accounts are not listed because the configuration is invalid.');
105
+ }
106
+ else {
107
+ try {
108
+ const raw = listMailboxesResult.parse(await deps.helper.run('list-mailboxes', {}));
109
+ const policy = computePolicy(deps.baseConfig, raw);
110
+ if (policy.accounts.length === 0)
111
+ add('accounts', 'warn', 'No visible account matches the configuration.');
112
+ policy.accounts.forEach((a, i) => {
113
+ const reason = unsupportedAccountReason(raw, a.id);
114
+ // Wie der Lese-Doctor: ohne --verbose keine Kontennamen oder -kennungen.
115
+ const label = deps.verbose ? `${a.name} (${a.id})` : `Account ${i + 1}`;
116
+ add(`account-${i + 1}`, reason === null ? 'ok' : 'warn', reason === null ? `${label}: supported.` : `${label}: unsupported, ${REASON_TEXT[reason]}.`);
117
+ });
118
+ }
119
+ catch {
120
+ add('accounts', 'warn', 'Accounts could not be listed.');
121
+ }
122
+ }
123
+ }
124
+ else {
125
+ add('message-id-header', 'warn', 'The header column and the accounts could not be checked because the Mail database is not readable (see above).');
126
+ }
127
+ for (const c of checks)
128
+ deps.out.write(`[${c.status}] ${c.id}: ${c.message}\n`);
129
+ return readExit !== 0 || checks.some((c) => c.status === 'fail') ? 1 : 0;
130
+ }
131
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import { loadConfig } from '@redpop/apple-mail-mcp/dist/config.js';
2
+ import { runCli as runReadCli } from '@redpop/apple-mail-mcp/dist/cli/main.js';
3
+ import { createHelperRunner } from '@redpop/apple-mail-mcp/dist/helper.js';
4
+ import { createActionsRunner } from '../bundle.js';
5
+ import { loadActionsConfig } from '../config.js';
6
+ import { defaultDoctorExec } from '@redpop/apple-mail-mcp/dist/cli/doctor.js';
7
+ import { runActionsDoctor } from './doctor.js';
8
+ import { runActionsSetup } from './setup.js';
9
+ const BASE_FALLBACK = {
10
+ accounts: [], includeJunk: false, includeTrash: false, excludeMailboxes: [], showSecurityMails: false,
11
+ bodySearch: true, bodyIndex: false, maxResults: 50, maxBodyChars: 20000, helperPath: null, debug: false,
12
+ };
13
+ /** Einstieg fuer `setup` und `doctor` des Actions-Pakets; beide Helper werden in jedem Fall gestoppt. */
14
+ export async function runCli(command, args, deps = {}) {
15
+ const env = deps.env ?? process.env;
16
+ const out = deps.out ?? process.stdout;
17
+ const baseResult = loadConfig(env);
18
+ const configResult = loadActionsConfig(env);
19
+ const baseConfig = baseResult.ok ? baseResult.config : null;
20
+ const helperOverride = env.APPLE_MAIL_HELPER_PATH?.trim();
21
+ const readConfig = baseConfig ?? { ...BASE_FALLBACK, helperPath: helperOverride ? helperOverride : null };
22
+ // Leere Kontenliste macht die Actions-Konfiguration ungueltig; Bundle-Pfad und Debug-Flag gelten trotzdem.
23
+ const actionsConfig = configResult.ok
24
+ ? configResult.config
25
+ : { ...readConfig, maxMoves: 25, excludeTargets: [], actionsPath: env.APPLE_MAIL_ACTIONS_PATH?.trim() || null };
26
+ const helper = (deps.makeHelper ?? createHelperRunner)(readConfig);
27
+ const actions = (deps.makeActions ?? createActionsRunner)(actionsConfig);
28
+ const stopAll = () => {
29
+ helper.stop();
30
+ actions.stop();
31
+ };
32
+ const onSignal = deps.onSignal ?? ((sig, h) => void process.on(sig, h));
33
+ const exit = deps.exit ?? ((c) => process.exit(c));
34
+ onSignal('SIGINT', () => { stopAll(); exit(130); });
35
+ onSignal('SIGTERM', () => { stopAll(); exit(143); });
36
+ // Der Lese-CLI bekommt den geteilten Helper; sein stop() ist ein No-op, gestoppt wird erst am Ende hier.
37
+ const shared = { ...helper, run: (c, p) => helper.run(c, p), stop: () => { } };
38
+ const readDeps = {
39
+ env, out, makeRunner: () => shared, onSignal: () => { }, exit: () => { }, setupAddHint: false,
40
+ ...(deps.isTTY !== undefined ? { isTTY: deps.isTTY } : {}),
41
+ };
42
+ const read = deps.readCli ?? runReadCli;
43
+ try {
44
+ if (command === 'setup') {
45
+ return await runActionsSetup({
46
+ readSetup: () => read('setup', args, readDeps), actions, out,
47
+ accounts: configResult.ok ? configResult.config.accounts.length : 0,
48
+ });
49
+ }
50
+ // --json und --schema sind Formate des Lese-Doctors; ihre Ausgabe bliebe sonst nicht maschinenlesbar.
51
+ if (args.includes('--json') || args.includes('--schema'))
52
+ return await read('doctor', args, readDeps);
53
+ return await runActionsDoctor({
54
+ readDoctor: () => read('doctor', args, readDeps),
55
+ helper, actions, configResult, baseConfig,
56
+ bundlePath: actions.bundlePath,
57
+ override: actionsConfig.actionsPath !== null,
58
+ exec: deps.exec ?? defaultDoctorExec,
59
+ out,
60
+ verbose: args.includes('--verbose'),
61
+ });
62
+ }
63
+ finally {
64
+ stopAll();
65
+ }
66
+ }
67
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { HelperError } from '@redpop/apple-mail-mcp/dist/errors.js';
2
+ import { describeActionsError } from '../errors.js';
3
+ const SETTINGS_LINE = 'System Settings > Privacy & Security > Automation';
4
+ /**
5
+ * `setup` des Actions-Pakets: erst Full Disk Access ueber das Lese-Setup, dann die Automation-Freigabe.
6
+ * Ohne Zugriff kein Automation-Dialog; der Dialog ist ein Apple Event und braucht laufendes Mail.
7
+ */
8
+ export async function runActionsSetup(deps) {
9
+ const say = (s) => void deps.out.write(s + '\n');
10
+ const fda = await deps.readSetup();
11
+ if (fda !== 0) {
12
+ say('');
13
+ say('Full Disk Access is not in place yet, so the Automation step was skipped. Fix the steps above, then run setup again.');
14
+ return 1;
15
+ }
16
+ say('');
17
+ say('Next: Mail MCP Actions needs permission to control Mail (Automation).');
18
+ let status;
19
+ try {
20
+ status = (await deps.actions.run('request-permission', {}))?.status;
21
+ }
22
+ catch (e) {
23
+ if (e instanceof HelperError && e.code === 'MAIL_NOT_RUNNING')
24
+ status = 'mail_not_running';
25
+ else if (e instanceof HelperError && e.code === 'AUTOMATION_NOT_GRANTED')
26
+ status = 'denied';
27
+ else {
28
+ say(e instanceof HelperError && e.code.startsWith('HELPER_') ? describeActionsError('ACTIONS_UNAVAILABLE') : 'The Mail MCP Actions app could not be asked for the permission.');
29
+ return 1;
30
+ }
31
+ }
32
+ switch (status) {
33
+ case 'granted':
34
+ say('Automation is allowed: Mail MCP Actions can control Mail.');
35
+ if (deps.accounts > 0)
36
+ say(`APPLE_MAIL_ACCOUNTS names ${deps.accounts} entr${deps.accounts === 1 ? 'y' : 'ies'}; the server moves messages only there.`);
37
+ else
38
+ say('Set APPLE_MAIL_ACCOUNTS to the accounts the server may move messages in; without it no message is ever moved.');
39
+ return 0;
40
+ case 'mail_not_running':
41
+ say('Mail is not running. macOS can only ask for the permission while Mail is open.');
42
+ say('Open Mail, then run setup again.');
43
+ return 1;
44
+ case 'denied':
45
+ say(`macOS refused the permission. Open ${SETTINGS_LINE}, switch on Mail under "Mail MCP Actions", then run setup again.`);
46
+ return 1;
47
+ default:
48
+ say('The permission dialog was dismissed or did not appear. Run setup again and choose OK.');
49
+ return 1;
50
+ }
51
+ }
52
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAA;AAEnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAWnD,MAAM,aAAa,GAAG,mDAAmD,CAAA;AAEzE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAsB;IAC1D,MAAM,GAAG,GAAG,CAAC,CAAS,EAAQ,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IAE9D,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAA;IAClC,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;QACd,GAAG,CAAC,EAAE,CAAC,CAAA;QACP,GAAG,CAAC,sHAAsH,CAAC,CAAA;QAC3H,OAAO,CAAC,CAAA;IACV,CAAC;IAED,GAAG,CAAC,EAAE,CAAC,CAAA;IACP,GAAG,CAAC,uEAAuE,CAAC,CAAA;IAC5E,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAiC,EAAE,MAAM,CAAA;IACtG,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,WAAW,IAAI,CAAC,CAAC,IAAI,KAAK,kBAAkB;YAAE,MAAM,GAAG,kBAAkB,CAAA;aACrF,IAAI,CAAC,YAAY,WAAW,IAAI,CAAC,CAAC,IAAI,KAAK,wBAAwB;YAAE,MAAM,GAAG,QAAQ,CAAA;aACtF,CAAC;YACJ,GAAG,CAAC,CAAC,YAAY,WAAW,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,iEAAiE,CAAC,CAAA;YAC/K,OAAO,CAAC,CAAA;QACV,CAAC;IACH,CAAC;IAED,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,SAAS;YACZ,GAAG,CAAC,2DAA2D,CAAC,CAAA;YAChE,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC;gBAAE,GAAG,CAAC,6BAA6B,IAAI,CAAC,QAAQ,QAAQ,IAAI,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,yCAAyC,CAAC,CAAA;;gBACnJ,GAAG,CAAC,+GAA+G,CAAC,CAAA;YACzH,OAAO,CAAC,CAAA;QACV,KAAK,kBAAkB;YACrB,GAAG,CAAC,gFAAgF,CAAC,CAAA;YACrF,GAAG,CAAC,kCAAkC,CAAC,CAAA;YACvC,OAAO,CAAC,CAAA;QACV,KAAK,QAAQ;YACX,GAAG,CAAC,sCAAsC,aAAa,kEAAkE,CAAC,CAAA;YAC1H,OAAO,CAAC,CAAA;QACV;YACE,GAAG,CAAC,uFAAuF,CAAC,CAAA;YAC5F,OAAO,CAAC,CAAA;IACZ,CAAC;AACH,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,49 @@
1
+ import { loadConfig } from '@redpop/apple-mail-mcp/dist/config.js';
2
+ // Gleiche Regeln wie in src/config.ts des Lesepakets (Platzhalter des MCPB-Hosts, leer = nicht gesetzt).
3
+ function raw(env, key) {
4
+ const t = env[key]?.trim();
5
+ if (t === undefined)
6
+ return undefined;
7
+ if (/\$\{user_config\.[^}]*\}/.test(t))
8
+ throw new KeyError(key, `${key} was not replaced by the MCPB host (it still reads ${t}); set a value or reinstall the extension`);
9
+ return t === '' ? undefined : t;
10
+ }
11
+ class KeyError extends Error {
12
+ key;
13
+ constructor(key, message) {
14
+ super(message);
15
+ this.key = key;
16
+ }
17
+ }
18
+ export function loadActionsConfig(env) {
19
+ const base = loadConfig(env);
20
+ if (!base.ok)
21
+ return base;
22
+ // Verschieben ohne Kontobegrenzung waere "alle Konten": hier ist die Liste Pflicht.
23
+ if (base.config.accounts.length === 0) {
24
+ return { ok: false, key: 'APPLE_MAIL_ACCOUNTS', error: 'APPLE_MAIL_ACCOUNTS must name at least one account; moving messages is never enabled for all accounts' };
25
+ }
26
+ try {
27
+ let maxMoves = 25;
28
+ const m = raw(env, 'APPLE_MAIL_MAX_MOVES');
29
+ if (m !== undefined) {
30
+ if (!/^\d+$/.test(m) || Number(m) < 1 || Number(m) > 100)
31
+ throw new KeyError('APPLE_MAIL_MAX_MOVES', 'APPLE_MAIL_MAX_MOVES must be an integer between 1 and 100');
32
+ maxMoves = Number(m);
33
+ }
34
+ let excludeTargets = [];
35
+ const x = raw(env, 'APPLE_MAIL_MOVE_EXCLUDE_TARGETS');
36
+ if (x !== undefined) {
37
+ excludeTargets = x.split(',').map((s) => s.trim()).filter((s) => s !== '');
38
+ if (excludeTargets.length === 0)
39
+ throw new KeyError('APPLE_MAIL_MOVE_EXCLUDE_TARGETS', 'APPLE_MAIL_MOVE_EXCLUDE_TARGETS contains no entries');
40
+ }
41
+ return { ok: true, config: { ...base.config, maxMoves, excludeTargets, actionsPath: raw(env, 'APPLE_MAIL_ACTIONS_PATH') ?? null } };
42
+ }
43
+ catch (e) {
44
+ if (e instanceof KeyError)
45
+ return { ok: false, key: e.key, error: e.message };
46
+ throw e;
47
+ }
48
+ }
49
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,UAAU,EAAE,MAAM,uCAAuC,CAAA;AAY/E,yGAAyG;AACzG,SAAS,GAAG,CAAC,GAAsB,EAAE,GAAW;IAC9C,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAA;IAC1B,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACrC,IAAI,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,sDAAsD,CAAC,2CAA2C,CAAC,CAAA;IACzK,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;AACjC,CAAC;AAED,MAAM,QAAS,SAAQ,KAAK;IACL,GAAG;IAAxB,YAAqB,GAAW,EAAE,OAAe;QAC/C,KAAK,CAAC,OAAO,CAAC,CAAA;mBADK,GAAG;IAExB,CAAC;CACF;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAsB;IACtD,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;IAC5B,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAA;IACzB,oFAAoF;IACpF,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,qBAAqB,EAAE,KAAK,EAAE,uGAAuG,EAAE,CAAA;IAClK,CAAC;IACD,IAAI,CAAC;QACH,IAAI,QAAQ,GAAG,EAAE,CAAA;QACjB,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAA;QAC1C,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YACpB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG;gBAAE,MAAM,IAAI,QAAQ,CAAC,sBAAsB,EAAE,2DAA2D,CAAC,CAAA;YACjK,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;QACtB,CAAC;QACD,IAAI,cAAc,GAAa,EAAE,CAAA;QACjC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,EAAE,iCAAiC,CAAC,CAAA;QACrD,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YACpB,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;YAC1E,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM,IAAI,QAAQ,CAAC,iCAAiC,EAAE,qDAAqD,CAAC,CAAA;QAC/I,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,GAAG,CAAC,GAAG,EAAE,yBAAyB,CAAC,IAAI,IAAI,EAAE,EAAE,CAAA;IACrI,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,QAAQ;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAA;QAC7E,MAAM,CAAC,CAAA;IACT,CAAC;AACH,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { HelperError } from '@redpop/apple-mail-mcp/dist/errors.js';
2
+ import { defaultOpen, openFdaOnce } from '@redpop/apple-mail-mcp/dist/fdaPrompt.js';
3
+ import { readBundleName } from '@redpop/apple-mail-mcp/dist/signing.js';
4
+ import { defaultLockFile, MoveLocks } from './locks.js';
5
+ export function createActionsContext(deps) {
6
+ const open = deps.open ?? defaultOpen;
7
+ const config = () => {
8
+ if (!deps.configResult.ok)
9
+ throw new HelperError('CONFIG_INVALID', deps.configResult.key);
10
+ return deps.configResult.config;
11
+ };
12
+ const helperName = deps.helperName ?? (deps.helperBundlePath === '' ? 'Mail MCP Helper' : readBundleName(deps.helperBundlePath));
13
+ // respond() braucht nur diese drei Felder; der Rest von ToolContext gehoert dem Lesepaket (Policy-Cache, Body-Index).
14
+ const respondContext = {
15
+ bundlePath: deps.helperBundlePath,
16
+ helperName,
17
+ onHelperError: (e) => (e instanceof HelperError && e.code === 'FULL_DISK_ACCESS_REQUIRED' ? openFdaOnce(deps.helperBundlePath, open) : false),
18
+ };
19
+ return {
20
+ config,
21
+ helper: deps.helper,
22
+ actions: deps.actions,
23
+ locks: deps.locks ?? new MoveLocks(defaultLockFile()),
24
+ respondContext,
25
+ };
26
+ }
27
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAA;AACnE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAe,MAAM,0CAA0C,CAAA;AAEhG,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAA;AAGvE,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAevD,MAAM,UAAU,oBAAoB,CAAC,IASpC;IACC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,WAAW,CAAA;IACrC,MAAM,MAAM,GAAG,GAAkB,EAAE;QACjC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE;YAAE,MAAM,IAAI,WAAW,CAAC,gBAAgB,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;QACzF,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAA;IACjC,CAAC,CAAA;IACD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,gBAAgB,KAAK,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAA;IAChI,sHAAsH;IACtH,MAAM,cAAc,GAAG;QACrB,UAAU,EAAE,IAAI,CAAC,gBAAgB;QACjC,UAAU;QACV,aAAa,EAAE,CAAC,CAAU,EAAW,EAAE,CAAC,CAAC,CAAC,YAAY,WAAW,IAAI,CAAC,CAAC,IAAI,KAAK,2BAA2B,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;KACtI,CAAA;IAC3B,OAAO;QACL,MAAM;QACN,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,SAAS,CAAC,eAAe,EAAE,CAAC;QACrD,cAAc;KACf,CAAA;AACH,CAAC"}
package/dist/errors.js ADDED
@@ -0,0 +1,24 @@
1
+ /** Fehler mit einem Code, den describeActionsError in einen englischen Satz fuer das Modell uebersetzt. */
2
+ export class ActionsError extends Error {
3
+ code;
4
+ constructor(code, message) {
5
+ super(message ?? code);
6
+ this.code = code;
7
+ this.name = 'ActionsError';
8
+ }
9
+ }
10
+ const TEXTS = {
11
+ MAIL_NOT_RUNNING: 'Mail.app is not running. Moving messages needs it. Ask the user to open Mail and retry.',
12
+ AUTOMATION_NOT_GRANTED: 'macOS has not allowed "Mail MCP Actions" to control Mail. The user needs to open System Settings > Privacy & Security > Automation, ' +
13
+ 'switch on Mail under "Mail MCP Actions", and retry.',
14
+ MOVE_FAILED: 'Mail did not move the message. Nothing was changed for this message; it may have been moved or deleted in the meantime.',
15
+ LOCK_UNAVAILABLE: 'The move protection file could not be read or written, so no message was moved. This is a local problem; ask the user to check that ~/Library/Application Support/apple-mail-mcp/move-locks.json is a readable, writable file and to try again.',
16
+ ACTIONS_BUNDLE_MISSING: 'The Mail MCP Actions app is missing from the installation, so no message was moved. Reinstalling the package should restore it.',
17
+ ACTIONS_SIGNATURE_INVALID: 'The Mail MCP Actions app is not signed correctly and was not started, so no message was moved. The user should reinstall the package from the official source.',
18
+ ACTIONS_UNAVAILABLE: 'The Mail MCP Actions app could not be started or did not answer in time, so no message was moved. Retrying starts it again; if it persists, ask the user to run the doctor command.',
19
+ ACTIONS_UNEXPECTED_ANSWER: 'The Mail MCP Actions app gave an answer this server does not understand, so no move was attempted and nothing was changed. Ask the user to run the doctor command.',
20
+ };
21
+ export function describeActionsError(code) {
22
+ return TEXTS[code] ?? `The move failed with the unexpected error code ${code}.`;
23
+ }
24
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA,2GAA2G;AAC3G,MAAM,OAAO,YAAa,SAAQ,KAAK;IAE1B,IAAI;IADf,YACW,IAAY,EACrB,OAAgB;QAEhB,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,CAAA;oBAHb,IAAI;QAIb,IAAI,CAAC,IAAI,GAAG,cAAc,CAAA;IAC5B,CAAC;CACF;AAED,MAAM,KAAK,GAAqC;IAC9C,gBAAgB,EAAE,yFAAyF;IAC3G,sBAAsB,EACpB,sIAAsI;QACtI,qDAAqD;IACvD,WAAW,EAAE,yHAAyH;IACtI,gBAAgB,EACd,iPAAiP;IACnP,sBAAsB,EAAE,iIAAiI;IACzJ,yBAAyB,EACvB,gKAAgK;IAClK,mBAAmB,EACjB,qLAAqL;IACvL,yBAAyB,EACvB,oKAAoK;CACvK,CAAA;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAQ,KAAgC,CAAC,IAAI,CAAC,IAAI,kDAAkD,IAAI,GAAG,CAAA;AAC7G,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from '@modelcontextprotocol/server/stdio';
3
+ import { createHelperRunner } from '@redpop/apple-mail-mcp/dist/helper.js';
4
+ import { createActionsRunner } from './bundle.js';
5
+ import { loadActionsConfig } from './config.js';
6
+ import { createActionsContext } from './context.js';
7
+ import { createServer } from './server.js';
8
+ // Auf stdout darf im Servermodus nur das Protokoll stehen; setup/doctor sind eigene Kommandozeilenmodi.
9
+ const arg = process.argv[2];
10
+ if (arg === 'setup' || arg === 'doctor') {
11
+ const { runCli } = await import('./cli/main.js');
12
+ process.exit(await runCli(arg, process.argv.slice(3)));
13
+ }
14
+ const configResult = loadActionsConfig(process.env);
15
+ const unreachable = { bundlePath: '', run: () => Promise.reject(new Error('unreachable')), stop: () => { } };
16
+ // Ungueltige Konfiguration: Server startet trotzdem, jeder Aufruf scheitert vorher mit CONFIG_INVALID.
17
+ const helper = configResult.ok ? createHelperRunner(configResult.config) : unreachable;
18
+ const actions = configResult.ok ? createActionsRunner(configResult.config) : unreachable;
19
+ const ctx = createActionsContext({ helper, actions, configResult, helperBundlePath: helper.bundlePath });
20
+ const server = createServer(ctx);
21
+ const shutdown = () => {
22
+ helper.stop();
23
+ actions.stop();
24
+ };
25
+ // Bei einem Signal raeumt Node die Pipes nicht auf; ohne stop() blieben die Kindprozesse verwaist.
26
+ for (const signal of ['SIGINT', 'SIGTERM']) {
27
+ process.on(signal, () => {
28
+ shutdown();
29
+ process.exit(0);
30
+ });
31
+ }
32
+ // EOF auf stdin schliesst den Transport; dann duerfen die Kindprozesse nicht ueberleben.
33
+ server.server.onclose = () => {
34
+ shutdown();
35
+ process.exit(0);
36
+ };
37
+ await server.connect(new StdioServerTransport());
38
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAA;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAA;AAE1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,wGAAwG;AACxG,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAC3B,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;IACxC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;IAChD,OAAO,CAAC,IAAI,CAAC,MAAM,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACxD,CAAC;AAED,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;AAEnD,MAAM,WAAW,GAAc,EAAE,UAAU,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAA;AACtH,uGAAuG;AACvG,MAAM,MAAM,GAAc,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAA;AACjG,MAAM,OAAO,GAAc,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAA;AAEnG,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAA;AACxG,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;AAEhC,MAAM,QAAQ,GAAG,GAAS,EAAE;IAC1B,MAAM,CAAC,IAAI,EAAE,CAAA;IACb,OAAO,CAAC,IAAI,EAAE,CAAA;AAChB,CAAC,CAAA;AAED,mGAAmG;AACnG,KAAK,MAAM,MAAM,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAU,EAAE,CAAC;IACpD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;QACtB,QAAQ,EAAE,CAAA;QACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,yFAAyF;AACzF,MAAM,CAAC,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE;IAC3B,QAAQ,EAAE,CAAA;IACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAA;AAED,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAA"}