@bobfrankston/rmfmail 1.2.128 → 1.2.130

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,203 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * rmfmail-mcp — Model Context Protocol server over the running rmfmail
4
+ * daemon, so an AI (Claude Code, Claude Desktop, anything MCP-speaking) can
5
+ * process mail on the user's behalf.
6
+ *
7
+ * claude mcp add rmfmail -- rmfmail-mcp
8
+ *
9
+ * Transport: MCP stdio (newline-delimited JSON-RPC 2.0). Hand-rolled — the
10
+ * protocol subset needed (initialize / tools/list / tools/call) is ~100
11
+ * lines and not worth an SDK dependency.
12
+ *
13
+ * Backend: the daemon's /rpc endpoint, discovered via ~/.rmfmail/agent.json
14
+ * (written each boot, removed on shutdown; a dead pid means stale). Scope:
15
+ * the TRIAGE token by default — reads plus flag/mark-read. Set
16
+ * RMFMAIL_MCP_FULL=1 to use the full token, which unlocks move_message and
17
+ * create_draft. There is deliberately NO send tool at either scope: AI
18
+ * drafts, the human sends (standing policy).
19
+ */
20
+ import fs from "node:fs";
21
+ import path from "node:path";
22
+ import readline from "node:readline";
23
+ const CONFIG_DIR = path.join(process.env.USERPROFILE || process.env.HOME || ".", ".rmfmail");
24
+ const AGENT_JSON = path.join(CONFIG_DIR, "agent.json");
25
+ const FULL = process.env.RMFMAIL_MCP_FULL === "1";
26
+ function loadAgentInfo() {
27
+ let raw;
28
+ try {
29
+ raw = fs.readFileSync(AGENT_JSON, "utf-8");
30
+ }
31
+ catch {
32
+ throw new Error(`rmfmail daemon not running (no ${AGENT_JSON}) — start it with: rmfmail`);
33
+ }
34
+ const info = JSON.parse(raw);
35
+ try {
36
+ process.kill(info.pid, 0);
37
+ }
38
+ catch {
39
+ throw new Error(`agent.json is stale (pid ${info.pid} not running) — start rmfmail`);
40
+ }
41
+ return info;
42
+ }
43
+ let rpcSeq = 0;
44
+ async function rpc(action, params = {}) {
45
+ const info = loadAgentInfo();
46
+ const token = FULL ? info.tokens.full : info.tokens.triage;
47
+ const r = await fetch(`${info.rpcUrl}?t=${token}`, {
48
+ method: "POST",
49
+ headers: { "content-type": "application/json" },
50
+ body: JSON.stringify({ _action: action, _cbid: String(++rpcSeq), ...params }),
51
+ });
52
+ if (!r.ok)
53
+ throw new Error(`daemon rpc HTTP ${r.status}`);
54
+ const res = await r.json();
55
+ if (res.error)
56
+ throw new Error(res.error);
57
+ return res.result;
58
+ }
59
+ // ── Tools ──
60
+ /** Trim a message object down to what an LLM needs — full envelopes carry
61
+ * parsed MIME internals that waste context. */
62
+ function slimMessage(m, includeBody) {
63
+ const addr = (a) => Array.isArray(a) ? a.map((x) => x.name ? `${x.name} <${x.address}>` : x.address).join(", ") : a;
64
+ const out = {
65
+ accountId: m.accountId, uid: m.uid, folderId: m.folderId,
66
+ date: m.date, from: addr(m.from), to: addr(m.to), cc: addr(m.cc) || undefined,
67
+ subject: m.subject, seen: m.seen, flagged: m.flagged,
68
+ snippet: m.preview || undefined,
69
+ };
70
+ if (includeBody) {
71
+ out.bodyText = m.bodyText || undefined;
72
+ // Fall back to a crude strip when only HTML exists.
73
+ if (!out.bodyText && m.bodyHtml)
74
+ out.bodyText = String(m.bodyHtml).replace(/<style[\s\S]*?<\/style>/gi, "").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim().slice(0, 20000);
75
+ if (m.bodyError)
76
+ out.bodyError = m.bodyError;
77
+ if (Array.isArray(m.attachments) && m.attachments.length) {
78
+ out.attachments = m.attachments.map((a) => ({ id: a.id, filename: a.filename, mimeType: a.mimeType, size: a.size }));
79
+ }
80
+ }
81
+ return out;
82
+ }
83
+ const str = (description) => ({ type: "string", description });
84
+ const num = (description) => ({ type: "number", description });
85
+ const bool = (description) => ({ type: "boolean", description });
86
+ const obj = (props, required) => ({ type: "object", properties: props, required });
87
+ const TOOLS = {
88
+ list_accounts: {
89
+ description: "List configured mail accounts (id, name, email).",
90
+ inputSchema: obj({}, []),
91
+ run: async () => (await rpc("getAccounts")).map((a) => ({ id: a.id, name: a.name, email: a.email })),
92
+ },
93
+ list_folders: {
94
+ description: "List folders for an account, with unread/total counts.",
95
+ inputSchema: obj({ accountId: str("Account id from list_accounts") }, ["accountId"]),
96
+ run: async (a) => (await rpc("getFolders", { accountId: a.accountId })).map((f) => ({ id: f.id, path: f.path, specialUse: f.specialUse || undefined, unread: f.unreadCount, total: f.totalCount })),
97
+ },
98
+ list_messages: {
99
+ description: "List messages in a folder, newest first (paged, 50/page). Returns envelopes with snippets, no bodies.",
100
+ inputSchema: obj({ accountId: str("Account id"), folderId: num("Folder id from list_folders"), page: num("1-based page, default 1") }, ["accountId", "folderId"]),
101
+ run: async (a) => {
102
+ const r = await rpc("getMessages", { accountId: a.accountId, folderId: a.folderId, page: a.page || 1, pageSize: 50 });
103
+ return { total: r.total, messages: (r.messages || []).map((m) => slimMessage({ ...m, accountId: a.accountId, folderId: a.folderId }, false)) };
104
+ },
105
+ },
106
+ search_messages: {
107
+ description: "Full-text search across all local mail (FTS). Query supports plain words; results span accounts/folders.",
108
+ inputSchema: obj({ query: str("Search text"), includeTrashSpam: bool("Also search Trash/Spam (default false)") }, ["query"]),
109
+ run: async (a) => {
110
+ const r = await rpc("searchMessages", { query: (a.query || "").trim(), page: 1, pageSize: 50, scope: "all", accountId: "", folderId: 0, includeTrashSpam: !!a.includeTrashSpam });
111
+ return { total: r.total, messages: (r.messages || []).map((m) => slimMessage(m, false)) };
112
+ },
113
+ },
114
+ get_message: {
115
+ description: "Fetch one message including its text body and attachment list.",
116
+ inputSchema: obj({ accountId: str("Account id"), uid: num("Message uid"), folderId: num("Folder id the uid lives in") }, ["accountId", "uid", "folderId"]),
117
+ run: async (a) => slimMessage(await rpc("getMessage", { accountId: a.accountId, uid: a.uid, folderId: a.folderId, allowRemote: false }), true),
118
+ },
119
+ flag_message: {
120
+ description: "Set or clear flags on a message. flags is the COMPLETE new flag list, e.g. [\"\\\\Seen\", \"\\\\Flagged\"] or [\"\\\\Seen\"] to unflag.",
121
+ inputSchema: obj({ accountId: str("Account id"), uid: num("Message uid"), folderId: num("Folder id"), flags: { type: "array", items: { type: "string" }, description: "Complete flag list" } }, ["accountId", "uid", "folderId", "flags"]),
122
+ run: async (a) => rpc("updateFlags", { accountId: a.accountId, uid: a.uid, folderId: a.folderId, flags: a.flags }),
123
+ },
124
+ move_message: {
125
+ description: "Move a message to another folder (same account). FULL scope only.",
126
+ inputSchema: obj({ accountId: str("Account id"), uid: num("Message uid"), folderId: num("Source folder id"), targetFolderId: num("Destination folder id") }, ["accountId", "uid", "folderId", "targetFolderId"]),
127
+ fullOnly: true,
128
+ run: async (a) => rpc("moveMessages", { accountId: a.accountId, uids: [a.uid], folderIds: [a.folderId], targetFolderId: a.targetFolderId }),
129
+ },
130
+ create_draft: {
131
+ description: "Create a draft (NOT sent — drafts are for the human to review and send). FULL scope only.",
132
+ inputSchema: obj({ accountId: str("Account id to draft from"), to: str("To recipients, comma-separated"), cc: str("Cc recipients (optional)"), subject: str("Subject"), bodyText: str("Plain-text body") }, ["accountId", "to", "subject", "bodyText"]),
133
+ fullOnly: true,
134
+ run: async (a) => rpc("saveDraft", { accountId: a.accountId, subject: a.subject, bodyHtml: String(a.bodyText).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/\n/g, "<br>"), bodyText: a.bodyText, to: a.to, cc: a.cc || "" }),
135
+ },
136
+ };
137
+ // ── MCP stdio plumbing (JSON-RPC 2.0, one message per line) ──
138
+ const out = (msg) => { process.stdout.write(JSON.stringify(msg) + "\n"); };
139
+ function toolList() {
140
+ return Object.entries(TOOLS)
141
+ .filter(([, t]) => FULL || !t.fullOnly)
142
+ .map(([name, t]) => ({ name, description: t.description, inputSchema: t.inputSchema }));
143
+ }
144
+ const rl = readline.createInterface({ input: process.stdin, terminal: false });
145
+ rl.on("line", (line) => { void handle(line); });
146
+ async function handle(line) {
147
+ if (!line.trim())
148
+ return;
149
+ let req;
150
+ try {
151
+ req = JSON.parse(line);
152
+ }
153
+ catch {
154
+ return;
155
+ }
156
+ const { id, method, params } = req;
157
+ const reply = (result) => out({ jsonrpc: "2.0", id, result });
158
+ const fail = (code, message) => out({ jsonrpc: "2.0", id, error: { code, message } });
159
+ try {
160
+ switch (method) {
161
+ case "initialize":
162
+ reply({
163
+ protocolVersion: params?.protocolVersion || "2024-11-05",
164
+ capabilities: { tools: {} },
165
+ serverInfo: { name: "rmfmail", version: "1.0.0" },
166
+ instructions: `Email triage over the local rmfmail daemon (scope: ${FULL ? "full — includes move + draft creation" : "triage — reads and flags only"}). There is no send tool: draft, never send.`,
167
+ });
168
+ return;
169
+ case "notifications/initialized":
170
+ case "notifications/cancelled":
171
+ return; // notifications get no response
172
+ case "tools/list":
173
+ reply({ tools: toolList() });
174
+ return;
175
+ case "tools/call": {
176
+ const tool = TOOLS[params?.name];
177
+ if (!tool || (tool.fullOnly && !FULL)) {
178
+ fail(-32602, `unknown tool: ${params?.name}`);
179
+ return;
180
+ }
181
+ try {
182
+ const result = await tool.run(params?.arguments || {});
183
+ reply({ content: [{ type: "text", text: JSON.stringify(result, null, 1) }] });
184
+ }
185
+ catch (e) {
186
+ reply({ content: [{ type: "text", text: `Error: ${e?.message || e}` }], isError: true });
187
+ }
188
+ return;
189
+ }
190
+ case "ping":
191
+ reply({});
192
+ return;
193
+ default:
194
+ if (id !== undefined)
195
+ fail(-32601, `method not found: ${method}`);
196
+ }
197
+ }
198
+ catch (e) {
199
+ if (id !== undefined)
200
+ fail(-32603, e?.message || String(e));
201
+ }
202
+ }
203
+ //# sourceMappingURL=mcp-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["mcp-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,199 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * rmfmail-mcp — Model Context Protocol server over the running rmfmail
4
+ * daemon, so an AI (Claude Code, Claude Desktop, anything MCP-speaking) can
5
+ * process mail on the user's behalf.
6
+ *
7
+ * claude mcp add rmfmail -- rmfmail-mcp
8
+ *
9
+ * Transport: MCP stdio (newline-delimited JSON-RPC 2.0). Hand-rolled — the
10
+ * protocol subset needed (initialize / tools/list / tools/call) is ~100
11
+ * lines and not worth an SDK dependency.
12
+ *
13
+ * Backend: the daemon's /rpc endpoint, discovered via ~/.rmfmail/agent.json
14
+ * (written each boot, removed on shutdown; a dead pid means stale). Scope:
15
+ * the TRIAGE token by default — reads plus flag/mark-read. Set
16
+ * RMFMAIL_MCP_FULL=1 to use the full token, which unlocks move_message and
17
+ * create_draft. There is deliberately NO send tool at either scope: AI
18
+ * drafts, the human sends (standing policy).
19
+ */
20
+
21
+ import fs from "node:fs";
22
+ import path from "node:path";
23
+ import readline from "node:readline";
24
+
25
+ const CONFIG_DIR = path.join(process.env.USERPROFILE || process.env.HOME || ".", ".rmfmail");
26
+ const AGENT_JSON = path.join(CONFIG_DIR, "agent.json");
27
+ const FULL = process.env.RMFMAIL_MCP_FULL === "1";
28
+
29
+ interface AgentInfo { rpcUrl: string; tokens: { triage: string; full: string }; pid: number; version: string }
30
+
31
+ function loadAgentInfo(): AgentInfo {
32
+ let raw: string;
33
+ try { raw = fs.readFileSync(AGENT_JSON, "utf-8"); }
34
+ catch { throw new Error(`rmfmail daemon not running (no ${AGENT_JSON}) — start it with: rmfmail`); }
35
+ const info = JSON.parse(raw) as AgentInfo;
36
+ try { process.kill(info.pid, 0); }
37
+ catch { throw new Error(`agent.json is stale (pid ${info.pid} not running) — start rmfmail`); }
38
+ return info;
39
+ }
40
+
41
+ let rpcSeq = 0;
42
+ async function rpc(action: string, params: Record<string, any> = {}): Promise<any> {
43
+ const info = loadAgentInfo();
44
+ const token = FULL ? info.tokens.full : info.tokens.triage;
45
+ const r = await fetch(`${info.rpcUrl}?t=${token}`, {
46
+ method: "POST",
47
+ headers: { "content-type": "application/json" },
48
+ body: JSON.stringify({ _action: action, _cbid: String(++rpcSeq), ...params }),
49
+ });
50
+ if (!r.ok) throw new Error(`daemon rpc HTTP ${r.status}`);
51
+ const res: any = await r.json();
52
+ if (res.error) throw new Error(res.error);
53
+ return res.result;
54
+ }
55
+
56
+ // ── Tools ──
57
+
58
+ /** Trim a message object down to what an LLM needs — full envelopes carry
59
+ * parsed MIME internals that waste context. */
60
+ function slimMessage(m: any, includeBody: boolean): any {
61
+ const addr = (a: any) => Array.isArray(a) ? a.map((x: any) => x.name ? `${x.name} <${x.address}>` : x.address).join(", ") : a;
62
+ const out: any = {
63
+ accountId: m.accountId, uid: m.uid, folderId: m.folderId,
64
+ date: m.date, from: addr(m.from), to: addr(m.to), cc: addr(m.cc) || undefined,
65
+ subject: m.subject, seen: m.seen, flagged: m.flagged,
66
+ snippet: m.preview || undefined,
67
+ };
68
+ if (includeBody) {
69
+ out.bodyText = m.bodyText || undefined;
70
+ // Fall back to a crude strip when only HTML exists.
71
+ if (!out.bodyText && m.bodyHtml) out.bodyText = String(m.bodyHtml).replace(/<style[\s\S]*?<\/style>/gi, "").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim().slice(0, 20000);
72
+ if (m.bodyError) out.bodyError = m.bodyError;
73
+ if (Array.isArray(m.attachments) && m.attachments.length) {
74
+ out.attachments = m.attachments.map((a: any) => ({ id: a.id, filename: a.filename, mimeType: a.mimeType, size: a.size }));
75
+ }
76
+ }
77
+ return out;
78
+ }
79
+
80
+ type Tool = {
81
+ description: string;
82
+ inputSchema: any;
83
+ fullOnly?: boolean;
84
+ run: (a: any) => Promise<any>;
85
+ };
86
+
87
+ const str = (description: string) => ({ type: "string", description });
88
+ const num = (description: string) => ({ type: "number", description });
89
+ const bool = (description: string) => ({ type: "boolean", description });
90
+ const obj = (props: any, required: string[]) => ({ type: "object", properties: props, required });
91
+
92
+ const TOOLS: Record<string, Tool> = {
93
+ list_accounts: {
94
+ description: "List configured mail accounts (id, name, email).",
95
+ inputSchema: obj({}, []),
96
+ run: async () => (await rpc("getAccounts")).map((a: any) => ({ id: a.id, name: a.name, email: a.email })),
97
+ },
98
+ list_folders: {
99
+ description: "List folders for an account, with unread/total counts.",
100
+ inputSchema: obj({ accountId: str("Account id from list_accounts") }, ["accountId"]),
101
+ run: async (a) => (await rpc("getFolders", { accountId: a.accountId })).map((f: any) => ({ id: f.id, path: f.path, specialUse: f.specialUse || undefined, unread: f.unreadCount, total: f.totalCount })),
102
+ },
103
+ list_messages: {
104
+ description: "List messages in a folder, newest first (paged, 50/page). Returns envelopes with snippets, no bodies.",
105
+ inputSchema: obj({ accountId: str("Account id"), folderId: num("Folder id from list_folders"), page: num("1-based page, default 1") }, ["accountId", "folderId"]),
106
+ run: async (a) => {
107
+ const r = await rpc("getMessages", { accountId: a.accountId, folderId: a.folderId, page: a.page || 1, pageSize: 50 });
108
+ return { total: r.total, messages: (r.messages || []).map((m: any) => slimMessage({ ...m, accountId: a.accountId, folderId: a.folderId }, false)) };
109
+ },
110
+ },
111
+ search_messages: {
112
+ description: "Full-text search across all local mail (FTS). Query supports plain words; results span accounts/folders.",
113
+ inputSchema: obj({ query: str("Search text"), includeTrashSpam: bool("Also search Trash/Spam (default false)") }, ["query"]),
114
+ run: async (a) => {
115
+ const r = await rpc("searchMessages", { query: (a.query || "").trim(), page: 1, pageSize: 50, scope: "all", accountId: "", folderId: 0, includeTrashSpam: !!a.includeTrashSpam });
116
+ return { total: r.total, messages: (r.messages || []).map((m: any) => slimMessage(m, false)) };
117
+ },
118
+ },
119
+ get_message: {
120
+ description: "Fetch one message including its text body and attachment list.",
121
+ inputSchema: obj({ accountId: str("Account id"), uid: num("Message uid"), folderId: num("Folder id the uid lives in") }, ["accountId", "uid", "folderId"]),
122
+ run: async (a) => slimMessage(await rpc("getMessage", { accountId: a.accountId, uid: a.uid, folderId: a.folderId, allowRemote: false }), true),
123
+ },
124
+ flag_message: {
125
+ description: "Set or clear flags on a message. flags is the COMPLETE new flag list, e.g. [\"\\\\Seen\", \"\\\\Flagged\"] or [\"\\\\Seen\"] to unflag.",
126
+ inputSchema: obj({ accountId: str("Account id"), uid: num("Message uid"), folderId: num("Folder id"), flags: { type: "array", items: { type: "string" }, description: "Complete flag list" } }, ["accountId", "uid", "folderId", "flags"]),
127
+ run: async (a) => rpc("updateFlags", { accountId: a.accountId, uid: a.uid, folderId: a.folderId, flags: a.flags }),
128
+ },
129
+ move_message: {
130
+ description: "Move a message to another folder (same account). FULL scope only.",
131
+ inputSchema: obj({ accountId: str("Account id"), uid: num("Message uid"), folderId: num("Source folder id"), targetFolderId: num("Destination folder id") }, ["accountId", "uid", "folderId", "targetFolderId"]),
132
+ fullOnly: true,
133
+ run: async (a) => rpc("moveMessages", { accountId: a.accountId, uids: [a.uid], folderIds: [a.folderId], targetFolderId: a.targetFolderId }),
134
+ },
135
+ create_draft: {
136
+ description: "Create a draft (NOT sent — drafts are for the human to review and send). FULL scope only.",
137
+ inputSchema: obj({ accountId: str("Account id to draft from"), to: str("To recipients, comma-separated"), cc: str("Cc recipients (optional)"), subject: str("Subject"), bodyText: str("Plain-text body") }, ["accountId", "to", "subject", "bodyText"]),
138
+ fullOnly: true,
139
+ run: async (a) => rpc("saveDraft", { accountId: a.accountId, subject: a.subject, bodyHtml: String(a.bodyText).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/\n/g, "<br>"), bodyText: a.bodyText, to: a.to, cc: a.cc || "" }),
140
+ },
141
+ };
142
+
143
+ // ── MCP stdio plumbing (JSON-RPC 2.0, one message per line) ──
144
+
145
+ const out = (msg: any): void => { process.stdout.write(JSON.stringify(msg) + "\n"); };
146
+
147
+ function toolList(): any[] {
148
+ return Object.entries(TOOLS)
149
+ .filter(([, t]) => FULL || !t.fullOnly)
150
+ .map(([name, t]) => ({ name, description: t.description, inputSchema: t.inputSchema }));
151
+ }
152
+
153
+ const rl = readline.createInterface({ input: process.stdin, terminal: false });
154
+ rl.on("line", (line) => { void handle(line); });
155
+
156
+ async function handle(line: string): Promise<void> {
157
+ if (!line.trim()) return;
158
+ let req: any;
159
+ try { req = JSON.parse(line); } catch { return; }
160
+ const { id, method, params } = req;
161
+ const reply = (result: any) => out({ jsonrpc: "2.0", id, result });
162
+ const fail = (code: number, message: string) => out({ jsonrpc: "2.0", id, error: { code, message } });
163
+ try {
164
+ switch (method) {
165
+ case "initialize":
166
+ reply({
167
+ protocolVersion: params?.protocolVersion || "2024-11-05",
168
+ capabilities: { tools: {} },
169
+ serverInfo: { name: "rmfmail", version: "1.0.0" },
170
+ instructions: `Email triage over the local rmfmail daemon (scope: ${FULL ? "full — includes move + draft creation" : "triage — reads and flags only"}). There is no send tool: draft, never send.`,
171
+ });
172
+ return;
173
+ case "notifications/initialized":
174
+ case "notifications/cancelled":
175
+ return; // notifications get no response
176
+ case "tools/list":
177
+ reply({ tools: toolList() });
178
+ return;
179
+ case "tools/call": {
180
+ const tool = TOOLS[params?.name];
181
+ if (!tool || (tool.fullOnly && !FULL)) { fail(-32602, `unknown tool: ${params?.name}`); return; }
182
+ try {
183
+ const result = await tool.run(params?.arguments || {});
184
+ reply({ content: [{ type: "text", text: JSON.stringify(result, null, 1) }] });
185
+ } catch (e: any) {
186
+ reply({ content: [{ type: "text", text: `Error: ${e?.message || e}` }], isError: true });
187
+ }
188
+ return;
189
+ }
190
+ case "ping":
191
+ reply({});
192
+ return;
193
+ default:
194
+ if (id !== undefined) fail(-32601, `method not found: ${method}`);
195
+ }
196
+ } catch (e: any) {
197
+ if (id !== undefined) fail(-32603, e?.message || String(e));
198
+ }
199
+ }
@@ -31,6 +31,18 @@ import { dispatch } from "@bobfrankston/mailx-service/jsonrpc.js";
31
31
  * window. Returns null if the server can't bind (popout disabled). */
32
32
  export async function startPopoutServer(svc, onAction) {
33
33
  const token = crypto.randomBytes(18).toString("hex");
34
+ const agentTokens = { triage: crypto.randomBytes(18).toString("hex"), full: crypto.randomBytes(18).toString("hex") };
35
+ // Actions a TRIAGE-scoped agent may call: reads plus flag/read-state.
36
+ // Deliberately excludes send/move/delete/settings and every popout/window
37
+ // action. Full-scope agents get the whole dispatcher.
38
+ const TRIAGE_ACTIONS = new Set([
39
+ "getVersion", "getAccounts", "getFolders", "getMessages", "getUnifiedInbox",
40
+ "getMessage", "searchMessages", "getThreadMessages", "getAttachment",
41
+ "getMessageSource", "searchContacts", "listContacts", "getCalendarEvents",
42
+ "getCalendars", "getTasks", "getOutboxStatus", "getSyncPending",
43
+ "getDiagnostics", "getPriorityLists", "hasCcHistoryTo", "hasBccHistoryTo",
44
+ "updateFlags", "markFolderRead", "logClientEvent",
45
+ ]);
34
46
  // Static root for /app/<token>/... — the app package root, so pages under
35
47
  // client/ can reach ../styles, ../../node_modules etc. exactly as they do
36
48
  // through msger's custom protocol.
@@ -49,11 +61,17 @@ export async function startPopoutServer(svc, onAction) {
49
61
  res.writeHead(403).end("forbidden");
50
62
  return;
51
63
  }
52
- await serveStatic(appRoot, staticMatch[2], token, res);
64
+ await serveStatic(appRoot, staticMatch[2], token, res, svc);
53
65
  return;
54
66
  }
55
67
  // Token gate on every request — loopback TCP is locally reachable.
56
- if (url.searchParams.get("t") !== token) {
68
+ // Three tokens: the per-launch window token (full surface), and two
69
+ // agent tokens published in ~/.rmfmail/agent.json.
70
+ const presented = url.searchParams.get("t");
71
+ const isWindowToken = presented === token;
72
+ const isFullAgent = presented === agentTokens.full;
73
+ const isTriageAgent = presented === agentTokens.triage;
74
+ if (!isWindowToken && !isFullAgent && !isTriageAgent) {
57
75
  res.writeHead(403).end("forbidden");
58
76
  return;
59
77
  }
@@ -90,6 +108,11 @@ export async function startPopoutServer(svc, onAction) {
90
108
  res.writeHead(400).end("bad rpc request");
91
109
  return;
92
110
  }
111
+ if (isTriageAgent && !TRIAGE_ACTIONS.has(rpcReq._action)) {
112
+ res.writeHead(200, { "content-type": "application/json", "cache-control": "no-store" });
113
+ res.end(JSON.stringify({ _cbid: rpcReq._cbid, error: `action "${rpcReq._action}" requires the full agent token (triage scope is reads + flags)` }));
114
+ return;
115
+ }
93
116
  const rpcRes = await dispatch(svc, rpcReq);
94
117
  res.writeHead(200, { "content-type": "application/json", "cache-control": "no-store" });
95
118
  res.end(JSON.stringify(rpcRes));
@@ -185,7 +208,7 @@ export async function startPopoutServer(svc, onAction) {
185
208
  const port = typeof addr === "object" && addr ? addr.port : 0;
186
209
  if (port) {
187
210
  console.log(` [popout] window server on http://127.0.0.1:${port} (loopback, token-gated)`);
188
- resolve({ port, token, broadcastEvent });
211
+ resolve({ port, token, agentTokens, broadcastEvent });
189
212
  }
190
213
  else {
191
214
  resolve(null);
@@ -211,7 +234,7 @@ const STATIC_MIME = {
211
234
  * the IPC-over-HTTP bridge injected at the top of <head>: config + bridge
212
235
  * (window.ipc → POST /rpc) + the REAL mailxapi.js — so the page runs the
213
236
  * byte-identical API surface the main WebView gets via initScript. */
214
- async function serveStatic(appRoot, relRaw, token, res) {
237
+ async function serveStatic(appRoot, relRaw, token, res, svc) {
215
238
  const rel = decodeURIComponent(relRaw);
216
239
  const abs = path.resolve(appRoot, rel);
217
240
  // Traversal guard — resolved path must stay inside the app root.
@@ -239,7 +262,18 @@ async function serveStatic(appRoot, relRaw, token, res) {
239
262
  // after parse but in DOCUMENT ORDER, so the bridge still executes
240
263
  // before the page's own module (compose.bundle.js) makes any RPC.
241
264
  // mailxapi.js stays classic — it's the same file every host injects.
242
- const inject = `<script>window.__rmfPopoutRpc={url:"/rpc?t=${token}",events:"/events?t=${token}"};</script>`
265
+ //
266
+ // Settings snapshot baked into the page: popout windows live on a
267
+ // per-port origin whose localStorage caches (editor type, font size)
268
+ // start EMPTY on every daemon restart — a reply opened in Quill when
269
+ // TinyMCE was selected (Bob 2026-07-12). Pages prefer this snapshot
270
+ // over their localStorage caches; ui subset keeps the payload small.
271
+ let bootUi = null;
272
+ try {
273
+ bootUi = (await svc?.getSettings?.())?.ui ?? null;
274
+ }
275
+ catch { /* page falls back to defaults */ }
276
+ const inject = `<script>window.__rmfPopoutRpc={url:"/rpc?t=${token}",events:"/events?t=${token}"};window.__rmfBootSettings=${JSON.stringify({ ui: bootUi })};</script>`
243
277
  + `<script type="module" src="/app/${token}/client/lib/popout-bridge.js"></script>`
244
278
  + `<script src="/app/${token}/client/lib/mailxapi.js"></script>`;
245
279
  const html = data.toString("utf-8").replace(/<head([^>]*)>/i, (m) => m + inject);
@@ -1 +1 @@
1
- {"version":3,"file":"popout-server.js","sourceRoot":"","sources":["popout-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"popout-server.js","sourceRoot":"","sources":["popout-server.ts"],"names":[],"mappings":"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"}