alienmail-mcp 1.0.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 (3) hide show
  1. package/README.md +90 -0
  2. package/mcp-server.mjs +719 -0
  3. package/package.json +24 -0
package/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # alienmail-mcp
2
+
3
+ Model Context Protocol (MCP) server for **AlienMail**. This package allows AI assistants (like Cursor, Claude, or Gemini) to securely interact with the AlienMail API to manage workspaces, marketing campaigns, leads, templates, and SMTP mailboxes directly from your AI workflows.
4
+
5
+ ## 🚀 Usage
6
+
7
+ You do not need to clone this repository to use the MCP server. You can run it directly using `npx` in your favorite MCP-compatible AI assistant.
8
+
9
+ ### MCP Configuration
10
+
11
+ Add the following configuration to your MCP client (e.g., Cursor or Claude Desktop):
12
+
13
+ ```json
14
+ {
15
+ "mcpServers": {
16
+ "alienmail-mcp": {
17
+ "command": "npx",
18
+ "args": [
19
+ "-y",
20
+ "alienmail-mcp"
21
+ ],
22
+ "env": {
23
+ "MCP_API_TOKEN": "your-alienmail-api-token"
24
+ }
25
+ }
26
+ }
27
+ }
28
+ ```
29
+
30
+ ## ⚙️ Environment Variables
31
+
32
+ The server requires the following environment variables to authenticate with the AlienMail backend:
33
+
34
+ - `MCP_API_TOKEN` (or `API_TOKEN`): **Required.** Your authentication JWT token to access the AlienMail API securely.
35
+ - `NEXT_PUBLIC_APP_URL`: *Optional.* The base URL of the AlienMail API. Defaults to `https://app.alienmail.io` if not provided.
36
+
37
+ ## 🛠️ Available Tools
38
+
39
+ Once connected, your AI assistant will have access to the following tools to manage your AlienMail platform:
40
+
41
+ ### 🏢 Workspaces
42
+ - `list_workspaces`: List all your accessible workspaces.
43
+ - `create_workspace`: Create a new workspace.
44
+
45
+ ### 📢 Campaigns
46
+ - `list_campaigns`: List campaigns for a workspace.
47
+ - `create_campaign`, `get_campaign`, `update_campaign`, `delete_campaign`
48
+ - `duplicate_campaign`, `start_campaign`, `toggle_campaign_status`, `update_campaign_settings`
49
+
50
+ ### 📧 Templates & Flow
51
+ - `list_templates`, `create_template`: Manage email templates for a campaign.
52
+ - `get_campaign_flow`, `save_campaign_flow`: Manage the nodes and edges for visual campaign flows.
53
+ - `get_campaign_conditions`, `create_campaign_condition`: Manage campaign trigger conditions (e.g., Opened an email).
54
+
55
+ ### 👥 Leads
56
+ - `list_leads`: List leads with pagination and search.
57
+ - `create_lead`, `import_leads_csv`, `get_lead`
58
+ - `bulk_update_lead_status`, `bulk_enroll_leads`
59
+ - `enroll_leads_in_campaign`: Enroll leads into a specific campaign.
60
+ - `get_lead_email_timeline`: Get email interaction timeline for a specific lead.
61
+
62
+ ### 📮 SMTP / Mailboxes
63
+ - `list_smtp_accounts`: View configured SMTP accounts.
64
+ - `add_smtp_account`, `update_smtp_account`, `delete_smtp_account`
65
+ - `test_smtp_connection`: Test your SMTP credentials.
66
+
67
+ ### 📊 Analytics
68
+ - `get_workspace_analytics`: Get aggregated analytics for a workspace within a date range.
69
+
70
+ ## 👨‍💻 Local Development
71
+
72
+ If you are developing or testing this package locally:
73
+
74
+ 1. Clone the repository and navigate into the directory.
75
+ 2. Install dependencies:
76
+ ```bash
77
+ npm install
78
+ ```
79
+ 3. Symlink the package globally to test `npx alienmail-mcp`:
80
+ ```bash
81
+ npm link
82
+ ```
83
+ 4. Run locally:
84
+ ```bash
85
+ npm start
86
+ ```
87
+
88
+ ## 📝 License
89
+
90
+ ISC
package/mcp-server.mjs ADDED
@@ -0,0 +1,719 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import {
5
+ CallToolRequestSchema,
6
+ ListToolsRequestSchema,
7
+ } from "@modelcontextprotocol/sdk/types.js";
8
+ import "dotenv/config";
9
+
10
+ // --- API State ---
11
+ const API_BASE_URL = process.env.NEXT_PUBLIC_APP_URL || "https://app.alienmail.io";
12
+ const API_TOKEN = process.env.MCP_API_TOKEN || process.env.API_TOKEN;
13
+
14
+ const server = new Server(
15
+ {
16
+ name: "project-access-mcp",
17
+ version: "1.0.0",
18
+ },
19
+ {
20
+ capabilities: {
21
+ tools: {},
22
+ },
23
+ }
24
+ );
25
+
26
+ async function makeApiCall(method, endpoint, body = null) {
27
+ const url = `${API_BASE_URL}${endpoint.startsWith('/') ? endpoint : `/${endpoint}`}`;
28
+ const headers = { "Content-Type": "application/json" };
29
+
30
+ if (API_TOKEN) {
31
+ headers.Authorization = `Bearer ${API_TOKEN}`;
32
+ headers.Cookie = `authToken=${API_TOKEN}`;
33
+ } else {
34
+ throw new Error("No API token configured. Please set MCP_API_TOKEN or API_TOKEN in your .env file or environment.");
35
+ }
36
+
37
+ const fetchOptions = {
38
+ method: method.toUpperCase(),
39
+ headers,
40
+ };
41
+ if (body && ["POST", "PUT", "PATCH"].includes(fetchOptions.method)) {
42
+ fetchOptions.body = JSON.stringify(body);
43
+ }
44
+
45
+ const response = await fetch(url, fetchOptions);
46
+ let responseBody;
47
+ const contentType = response.headers.get("content-type");
48
+ if (contentType && contentType.includes("application/json")) {
49
+ responseBody = await response.json();
50
+ } else {
51
+ responseBody = await response.text();
52
+ }
53
+
54
+ return {
55
+ content: [
56
+ { type: "text", text: `Status: ${response.status} ${response.statusText}\n\nResponse:\n${typeof responseBody === "string" ? responseBody : JSON.stringify(responseBody, null, 2)}` }
57
+ ],
58
+ };
59
+ }
60
+
61
+ // Define tools
62
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
63
+ return {
64
+ tools: [
65
+ // WORKSPACES
66
+ {
67
+ name: "list_workspaces",
68
+ description: "List all workspaces.",
69
+ inputSchema: { type: "object", properties: {} },
70
+ },
71
+ {
72
+ name: "create_workspace",
73
+ description: "Create a new workspace.",
74
+ inputSchema: {
75
+ type: "object",
76
+ properties: { name: { type: "string" } },
77
+ required: ["name"],
78
+ },
79
+ },
80
+ // CAMPAIGNS
81
+ {
82
+ name: "list_campaigns",
83
+ description: "List campaigns for a workspace.",
84
+ inputSchema: {
85
+ type: "object",
86
+ properties: {
87
+ workspaceUID: { type: "string" },
88
+ workspaceId: { type: "number" },
89
+ search: { type: "string" },
90
+ status: { type: "string" },
91
+ },
92
+ required: ["workspaceUID"],
93
+ },
94
+ },
95
+ {
96
+ name: "create_campaign",
97
+ description: "Create a new campaign.",
98
+ inputSchema: {
99
+ type: "object",
100
+ properties: {
101
+ workspaceUID: { type: "string" },
102
+ workspaceId: { type: "number" },
103
+ name: { type: "string" },
104
+ },
105
+ required: ["workspaceUID", "workspaceId", "name"],
106
+ },
107
+ },
108
+ {
109
+ name: "get_campaign",
110
+ description: "Get a campaign by ID.",
111
+ inputSchema: {
112
+ type: "object",
113
+ properties: {
114
+ workspaceUID: { type: "string" },
115
+ campaignId: { type: "number" },
116
+ },
117
+ required: ["workspaceUID", "campaignId"],
118
+ },
119
+ },
120
+ {
121
+ name: "update_campaign",
122
+ description: "Update a campaign name.",
123
+ inputSchema: {
124
+ type: "object",
125
+ properties: {
126
+ workspaceUID: { type: "string" },
127
+ campaignId: { type: "number" },
128
+ name: { type: "string" },
129
+ },
130
+ required: ["workspaceUID", "campaignId", "name"],
131
+ },
132
+ },
133
+ {
134
+ name: "delete_campaign",
135
+ description: "Soft delete a campaign.",
136
+ inputSchema: {
137
+ type: "object",
138
+ properties: {
139
+ workspaceUID: { type: "string" },
140
+ campaignId: { type: "number" },
141
+ },
142
+ required: ["workspaceUID", "campaignId"],
143
+ },
144
+ },
145
+ {
146
+ name: "duplicate_campaign",
147
+ description: "Duplicate a campaign.",
148
+ inputSchema: {
149
+ type: "object",
150
+ properties: {
151
+ workspaceUID: { type: "string" },
152
+ campaignId: { type: "number" },
153
+ },
154
+ required: ["workspaceUID", "campaignId"],
155
+ },
156
+ },
157
+ {
158
+ name: "start_campaign",
159
+ description: "Start a campaign.",
160
+ inputSchema: {
161
+ type: "object",
162
+ properties: {
163
+ workspaceUID: { type: "string" },
164
+ campaignId: { type: "number" },
165
+ },
166
+ required: ["workspaceUID", "campaignId"],
167
+ },
168
+ },
169
+ {
170
+ name: "toggle_campaign_status",
171
+ description: "Toggle a campaign's status.",
172
+ inputSchema: {
173
+ type: "object",
174
+ properties: {
175
+ workspaceUID: { type: "string" },
176
+ campaignId: { type: "number" },
177
+ status: { type: "string", description: "DRAFT, ACTIVE, PAUSED, COMPLETED" },
178
+ },
179
+ required: ["workspaceUID", "campaignId", "status"],
180
+ },
181
+ },
182
+ {
183
+ name: "update_campaign_settings",
184
+ description: "Update campaign settings.",
185
+ inputSchema: {
186
+ type: "object",
187
+ properties: {
188
+ workspaceUID: { type: "string" },
189
+ campaignId: { type: "number" },
190
+ emailsPerDay: { type: "number" },
191
+ gapBwEmail: { type: "number" },
192
+ startScheduleAt: { type: "string" },
193
+ endScheduleAt: { type: "string" },
194
+ },
195
+ required: ["workspaceUID", "campaignId", "emailsPerDay", "gapBwEmail"],
196
+ },
197
+ },
198
+ // CAMPAIGN TEMPLATES
199
+ {
200
+ name: "list_templates",
201
+ description: "List templates for a campaign.",
202
+ inputSchema: {
203
+ type: "object",
204
+ properties: {
205
+ workspaceUID: { type: "string" },
206
+ campaignId: { type: "number" },
207
+ },
208
+ required: ["workspaceUID", "campaignId"],
209
+ },
210
+ },
211
+ {
212
+ name: "create_template",
213
+ description: "Create a template for a campaign.",
214
+ inputSchema: {
215
+ type: "object",
216
+ properties: {
217
+ workspaceUID: { type: "string" },
218
+ campaignId: { type: "number" },
219
+ name: { type: "string" },
220
+ subject: { type: "string" },
221
+ html: { type: "string" },
222
+ enabled: { type: "boolean" },
223
+ stepIndex: { type: "number" },
224
+ },
225
+ required: ["workspaceUID", "campaignId", "name", "subject", "html"],
226
+ },
227
+ },
228
+ // CAMPAIGN FLOW
229
+ {
230
+ name: "get_campaign_flow",
231
+ description: "Get the flow (nodes and edges) of a campaign.",
232
+ inputSchema: {
233
+ type: "object",
234
+ properties: {
235
+ workspaceUID: { type: "string" },
236
+ campaignId: { type: "number" },
237
+ },
238
+ required: ["workspaceUID", "campaignId"],
239
+ },
240
+ },
241
+ {
242
+ name: "save_campaign_flow",
243
+ description: "Save the flow (nodes and edges) for a campaign.",
244
+ inputSchema: {
245
+ type: "object",
246
+ properties: {
247
+ workspaceUID: { type: "string" },
248
+ campaignId: { type: "number" },
249
+ nodes: { type: "array" },
250
+ edges: { type: "array" },
251
+ },
252
+ required: ["workspaceUID", "campaignId", "nodes", "edges"],
253
+ },
254
+ },
255
+ // CAMPAIGN CONDITIONS
256
+ {
257
+ name: "get_campaign_conditions",
258
+ description: "Get conditions for a campaign.",
259
+ inputSchema: {
260
+ type: "object",
261
+ properties: {
262
+ workspaceUID: { type: "string" },
263
+ campaignId: { type: "number" },
264
+ },
265
+ required: ["workspaceUID", "campaignId"],
266
+ },
267
+ },
268
+ {
269
+ name: "create_campaign_condition",
270
+ description: "Create a condition for a campaign.",
271
+ inputSchema: {
272
+ type: "object",
273
+ properties: {
274
+ workspaceUID: { type: "string" },
275
+ campaignId: { type: "number" },
276
+ name: { type: "string" },
277
+ condition: { type: "string", description: "Opened an email, Clicked on link, Has replied, All Leads" },
278
+ templateId: { type: "number" },
279
+ enabled: { type: "boolean" },
280
+ },
281
+ required: ["workspaceUID", "campaignId", "name", "condition", "templateId"],
282
+ },
283
+ },
284
+ // LEADS
285
+ {
286
+ name: "list_leads",
287
+ description: "List leads with pagination and optional search.",
288
+ inputSchema: {
289
+ type: "object",
290
+ properties: {
291
+ workspaceUID: { type: "string" },
292
+ page: { type: "number" },
293
+ pageSize: { type: "number" },
294
+ search: { type: "string" },
295
+ },
296
+ required: ["workspaceUID"],
297
+ },
298
+ },
299
+ {
300
+ name: "create_lead",
301
+ description: "Create a single lead.",
302
+ inputSchema: {
303
+ type: "object",
304
+ properties: {
305
+ workspaceUID: { type: "string" },
306
+ workspaceId: { type: "number" },
307
+ email: { type: "string" },
308
+ firstName: { type: "string" },
309
+ lastName: { type: "string" },
310
+ company: { type: "string" },
311
+ source: { type: "string" },
312
+ },
313
+ required: ["workspaceUID", "workspaceId", "email", "firstName"],
314
+ },
315
+ },
316
+ {
317
+ name: "import_leads_csv",
318
+ description: "Import leads via CSV.",
319
+ inputSchema: {
320
+ type: "object",
321
+ properties: {
322
+ workspaceUID: { type: "string" },
323
+ workspaceId: { type: "number" },
324
+ csv: { type: "string" },
325
+ },
326
+ required: ["workspaceUID", "workspaceId", "csv"],
327
+ },
328
+ },
329
+ {
330
+ name: "get_lead",
331
+ description: "Get a lead by ID with campaign analytics.",
332
+ inputSchema: {
333
+ type: "object",
334
+ properties: {
335
+ workspaceUID: { type: "string" },
336
+ leadId: { type: "number" },
337
+ },
338
+ required: ["workspaceUID", "leadId"],
339
+ },
340
+ },
341
+ {
342
+ name: "bulk_update_lead_status",
343
+ description: "Bulk update lead statuses.",
344
+ inputSchema: {
345
+ type: "object",
346
+ properties: {
347
+ workspaceUID: { type: "string" },
348
+ workspaceId: { type: "number" },
349
+ status: { type: "string" },
350
+ mode: { type: "string" },
351
+ selectedIds: { type: "array" },
352
+ excludedIds: { type: "array" },
353
+ search: { type: "string" },
354
+ },
355
+ required: ["workspaceUID", "workspaceId", "status", "mode"],
356
+ },
357
+ },
358
+ {
359
+ name: "bulk_enroll_leads",
360
+ description: "Bulk enroll leads into a campaign.",
361
+ inputSchema: {
362
+ type: "object",
363
+ properties: {
364
+ workspaceUID: { type: "string" },
365
+ workspaceId: { type: "number" },
366
+ campaignId: { type: "number" },
367
+ leads: { type: "array" },
368
+ },
369
+ required: ["workspaceUID", "workspaceId", "campaignId", "leads"],
370
+ },
371
+ },
372
+ // ENROLL LEADS INTO CAMPAIGN
373
+ {
374
+ name: "enroll_leads_in_campaign",
375
+ description: "Enroll leads into a specific campaign (by IDs or query).",
376
+ inputSchema: {
377
+ type: "object",
378
+ properties: {
379
+ workspaceUID: { type: "string" },
380
+ campaignId: { type: "number" },
381
+ workspaceId: { type: "number" },
382
+ mode: { type: "string" },
383
+ leadIds: { type: "array" },
384
+ search: { type: "string" },
385
+ excludedIds: { type: "array" },
386
+ },
387
+ required: ["workspaceUID", "campaignId", "workspaceId", "mode"],
388
+ },
389
+ },
390
+ {
391
+ name: "get_lead_email_timeline",
392
+ description: "Get email timeline for a lead in a campaign.",
393
+ inputSchema: {
394
+ type: "object",
395
+ properties: {
396
+ workspaceUID: { type: "string" },
397
+ campaignId: { type: "number" },
398
+ leadId: { type: "number" },
399
+ },
400
+ required: ["workspaceUID", "campaignId", "leadId"],
401
+ },
402
+ },
403
+ // SMTP / MAILBOX
404
+ {
405
+ name: "list_smtp_accounts",
406
+ description: "List SMTP accounts for a workspace.",
407
+ inputSchema: {
408
+ type: "object",
409
+ properties: {
410
+ workspaceUID: { type: "string" },
411
+ workspaceId: { type: "number" },
412
+ },
413
+ required: ["workspaceUID"],
414
+ },
415
+ },
416
+ {
417
+ name: "add_smtp_account",
418
+ description: "Add an SMTP account.",
419
+ inputSchema: {
420
+ type: "object",
421
+ properties: {
422
+ workspaceUID: { type: "string" },
423
+ workspaceId: { type: "number" },
424
+ host: { type: "string" },
425
+ port: { type: "number" },
426
+ username: { type: "string" },
427
+ password: { type: "string" },
428
+ fromEmail: { type: "string" },
429
+ fromName: { type: "string" },
430
+ },
431
+ required: ["workspaceUID", "workspaceId", "host", "port", "username", "password", "fromEmail", "fromName"],
432
+ },
433
+ },
434
+ {
435
+ name: "update_smtp_account",
436
+ description: "Update an SMTP account.",
437
+ inputSchema: {
438
+ type: "object",
439
+ properties: {
440
+ workspaceUID: { type: "string" },
441
+ id: { type: "number" },
442
+ host: { type: "string" },
443
+ port: { type: "number" },
444
+ username: { type: "string" },
445
+ fromEmail: { type: "string" },
446
+ fromName: { type: "string" },
447
+ },
448
+ required: ["workspaceUID", "id", "host", "port", "username", "fromEmail", "fromName"],
449
+ },
450
+ },
451
+ {
452
+ name: "delete_smtp_account",
453
+ description: "Delete an SMTP account.",
454
+ inputSchema: {
455
+ type: "object",
456
+ properties: {
457
+ workspaceUID: { type: "string" },
458
+ id: { type: "number" },
459
+ },
460
+ required: ["workspaceUID", "id"],
461
+ },
462
+ },
463
+ {
464
+ name: "test_smtp_connection",
465
+ description: "Test an SMTP connection.",
466
+ inputSchema: {
467
+ type: "object",
468
+ properties: {
469
+ workspaceUID: { type: "string" },
470
+ id: { type: "number" },
471
+ },
472
+ required: ["workspaceUID", "id"],
473
+ },
474
+ },
475
+ // ANALYTICS
476
+ {
477
+ name: "get_workspace_analytics",
478
+ description: "Get workspace analytics.",
479
+ inputSchema: {
480
+ type: "object",
481
+ properties: {
482
+ workspaceUID: { type: "string" },
483
+ from: { type: "string" },
484
+ to: { type: "string" },
485
+ status: { type: "string" },
486
+ },
487
+ required: ["workspaceUID", "from", "to"],
488
+ },
489
+ },
490
+ ],
491
+ };
492
+ });
493
+
494
+ // Handle tool execution
495
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
496
+ const { name, arguments: args } = request.params;
497
+
498
+ try {
499
+ // WORKSPACES
500
+ if (name === "list_workspaces") {
501
+ return await makeApiCall("GET", "/api/workspaces");
502
+ }
503
+ if (name === "create_workspace") {
504
+ return await makeApiCall("POST", "/api/workspaces", { name: args.name });
505
+ }
506
+
507
+ // CAMPAIGNS
508
+ if (name === "list_campaigns") {
509
+ const params = new URLSearchParams();
510
+ if (args.workspaceId) params.append("workspaceId", args.workspaceId.toString());
511
+ if (args.search) params.append("search", args.search);
512
+ if (args.status) params.append("status", args.status);
513
+ const queryStr = params.toString() ? `?${params.toString()}` : "";
514
+ return await makeApiCall("GET", `/api/${args.workspaceUID}/campaigns${queryStr}`);
515
+ }
516
+ if (name === "create_campaign") {
517
+ return await makeApiCall("POST", `/api/${args.workspaceUID}/campaigns`, {
518
+ name: args.name,
519
+ workspaceId: args.workspaceId,
520
+ });
521
+ }
522
+ if (name === "get_campaign") {
523
+ return await makeApiCall("GET", `/api/${args.workspaceUID}/campaigns/${args.campaignId}`);
524
+ }
525
+ if (name === "update_campaign") {
526
+ return await makeApiCall("PATCH", `/api/${args.workspaceUID}/campaigns/${args.campaignId}`, {
527
+ name: args.name,
528
+ });
529
+ }
530
+ if (name === "delete_campaign") {
531
+ return await makeApiCall("PATCH", `/api/${args.workspaceUID}/campaigns/${args.campaignId}/delete`);
532
+ }
533
+ if (name === "duplicate_campaign") {
534
+ return await makeApiCall("POST", `/api/${args.workspaceUID}/campaigns/${args.campaignId}/duplicate`);
535
+ }
536
+ if (name === "start_campaign") {
537
+ return await makeApiCall("POST", `/api/${args.workspaceUID}/campaigns/${args.campaignId}/start`);
538
+ }
539
+ if (name === "toggle_campaign_status") {
540
+ return await makeApiCall("POST", `/api/${args.workspaceUID}/campaigns/toggle`, {
541
+ id: args.campaignId,
542
+ status: args.status,
543
+ });
544
+ }
545
+ if (name === "update_campaign_settings") {
546
+ return await makeApiCall("PUT", `/api/${args.workspaceUID}/campaigns/${args.campaignId}/settings`, {
547
+ emailsPerDay: args.emailsPerDay,
548
+ gapBwEmail: args.gapBwEmail,
549
+ startScheduleAt: args.startScheduleAt,
550
+ endScheduleAt: args.endScheduleAt,
551
+ });
552
+ }
553
+
554
+ // CAMPAIGN TEMPLATES
555
+ if (name === "list_templates") {
556
+ return await makeApiCall("GET", `/api/${args.workspaceUID}/campaigns/${args.campaignId}/templates`);
557
+ }
558
+ if (name === "create_template") {
559
+ return await makeApiCall("POST", `/api/${args.workspaceUID}/campaigns/${args.campaignId}/templates`, {
560
+ name: args.name,
561
+ subject: args.subject,
562
+ html: args.html,
563
+ enabled: args.enabled !== undefined ? args.enabled : true,
564
+ stepIndex: args.stepIndex || 0,
565
+ });
566
+ }
567
+
568
+ // CAMPAIGN FLOW
569
+ if (name === "get_campaign_flow") {
570
+ return await makeApiCall("GET", `/api/${args.workspaceUID}/campaigns/${args.campaignId}/steps`);
571
+ }
572
+ if (name === "save_campaign_flow") {
573
+ return await makeApiCall("POST", `/api/${args.workspaceUID}/campaigns/${args.campaignId}/steps`, {
574
+ nodes: args.nodes,
575
+ edges: args.edges,
576
+ });
577
+ }
578
+
579
+ // CAMPAIGN CONDITIONS
580
+ if (name === "get_campaign_conditions") {
581
+ return await makeApiCall("GET", `/api/${args.workspaceUID}/campaigns/${args.campaignId}/conditions`);
582
+ }
583
+ if (name === "create_campaign_condition") {
584
+ return await makeApiCall("POST", `/api/${args.workspaceUID}/campaigns/${args.campaignId}/conditions`, {
585
+ name: args.name,
586
+ condition: args.condition,
587
+ templateId: args.templateId,
588
+ enabled: args.enabled !== undefined ? args.enabled : true,
589
+ });
590
+ }
591
+
592
+ // LEADS
593
+ if (name === "list_leads") {
594
+ const params = new URLSearchParams();
595
+ if (args.page) params.append("page", args.page.toString());
596
+ if (args.pageSize) params.append("pageSize", args.pageSize.toString());
597
+ if (args.search) params.append("search", args.search);
598
+ const queryStr = params.toString() ? `?${params.toString()}` : "";
599
+ return await makeApiCall("GET", `/api/${args.workspaceUID}/leads${queryStr}`);
600
+ }
601
+ if (name === "create_lead") {
602
+ return await makeApiCall("POST", `/api/${args.workspaceUID}/leads`, {
603
+ workspaceId: args.workspaceId,
604
+ email: args.email,
605
+ firstName: args.firstName,
606
+ lastName: args.lastName,
607
+ company: args.company,
608
+ source: args.source || "MANUAL",
609
+ });
610
+ }
611
+ if (name === "import_leads_csv") {
612
+ return await makeApiCall("POST", `/api/${args.workspaceUID}/leads`, {
613
+ workspaceId: args.workspaceId,
614
+ csv: args.csv,
615
+ });
616
+ }
617
+ if (name === "get_lead") {
618
+ return await makeApiCall("GET", `/api/${args.workspaceUID}/leads/${args.leadId}`);
619
+ }
620
+ if (name === "bulk_update_lead_status") {
621
+ return await makeApiCall("POST", `/api/${args.workspaceUID}/leads/bulk`, {
622
+ workspaceId: args.workspaceId,
623
+ status: args.status,
624
+ mode: args.mode,
625
+ selectedIds: args.selectedIds || [],
626
+ excludedIds: args.excludedIds || [],
627
+ search: args.search || "",
628
+ });
629
+ }
630
+ if (name === "bulk_enroll_leads") {
631
+ return await makeApiCall("POST", `/api/${args.workspaceUID}/leads/bulkenroll`, {
632
+ workspaceId: args.workspaceId,
633
+ campaignId: args.campaignId,
634
+ leads: args.leads,
635
+ });
636
+ }
637
+
638
+ // ENROLL LEADS INTO CAMPAIGN
639
+ if (name === "enroll_leads_in_campaign") {
640
+ return await makeApiCall("POST", `/api/${args.workspaceUID}/campaigns/${args.campaignId}/enroll`, {
641
+ workspaceId: args.workspaceId,
642
+ mode: args.mode,
643
+ leadIds: args.leadIds,
644
+ search: args.search,
645
+ excludedIds: args.excludedIds,
646
+ });
647
+ }
648
+ if (name === "get_lead_email_timeline") {
649
+ return await makeApiCall("GET", `/api/${args.workspaceUID}/campaigns/${args.campaignId}/lead/${args.leadId}`);
650
+ }
651
+
652
+ // SMTP / MAILBOX
653
+ if (name === "list_smtp_accounts") {
654
+ const params = new URLSearchParams();
655
+ if (args.workspaceId) params.append("workspaceId", args.workspaceId.toString());
656
+ const queryStr = params.toString() ? `?${params.toString()}` : "";
657
+ return await makeApiCall("GET", `/api/${args.workspaceUID}/smtp${queryStr}`);
658
+ }
659
+ if (name === "add_smtp_account") {
660
+ return await makeApiCall("POST", `/api/${args.workspaceUID}/smtp`, {
661
+ workspaceId: args.workspaceId,
662
+ host: args.host,
663
+ port: args.port,
664
+ username: args.username,
665
+ password: args.password,
666
+ fromEmail: args.fromEmail,
667
+ fromName: args.fromName,
668
+ });
669
+ }
670
+ if (name === "update_smtp_account") {
671
+ return await makeApiCall("PUT", `/api/${args.workspaceUID}/smtp`, {
672
+ id: args.id,
673
+ host: args.host,
674
+ port: args.port,
675
+ username: args.username,
676
+ fromEmail: args.fromEmail,
677
+ fromName: args.fromName,
678
+ });
679
+ }
680
+ if (name === "delete_smtp_account") {
681
+ const params = new URLSearchParams();
682
+ if (args.id) params.append("id", args.id.toString());
683
+ const queryStr = params.toString() ? `?${params.toString()}` : "";
684
+ return await makeApiCall("DELETE", `/api/${args.workspaceUID}/smtp${queryStr}`);
685
+ }
686
+ if (name === "test_smtp_connection") {
687
+ const params = new URLSearchParams();
688
+ if (args.id) params.append("id", args.id.toString());
689
+ const queryStr = params.toString() ? `?${params.toString()}` : "";
690
+ return await makeApiCall("GET", `/api/${args.workspaceUID}/smtp/test${queryStr}`);
691
+ }
692
+
693
+ // ANALYTICS
694
+ if (name === "get_workspace_analytics") {
695
+ const params = new URLSearchParams();
696
+ if (args.from) params.append("from", args.from);
697
+ if (args.to) params.append("to", args.to);
698
+ if (args.status) params.append("status", args.status);
699
+ const queryStr = params.toString() ? `?${params.toString()}` : "";
700
+ return await makeApiCall("GET", `/api/${args.workspaceUID}/analytics${queryStr}`);
701
+ }
702
+
703
+ throw new Error(`Unknown tool: ${name}`);
704
+ } catch (error) {
705
+ return {
706
+ content: [{ type: "text", text: `Error: ${error.message}` }],
707
+ isError: true,
708
+ };
709
+ }
710
+ });
711
+
712
+ // Start server
713
+ async function run() {
714
+ const transport = new StdioServerTransport();
715
+ await server.connect(transport);
716
+ console.error("Project Access MCP Server running on stdio");
717
+ }
718
+
719
+ run().catch(console.error);
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "alienmail-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for AlienMail",
5
+ "main": "mcp-server.mjs",
6
+ "type": "module",
7
+ "bin": {
8
+ "alienmail-mcp": "./mcp-server.mjs"
9
+ },
10
+ "scripts": {
11
+ "start": "node mcp-server.mjs"
12
+ },
13
+ "dependencies": {
14
+ "@modelcontextprotocol/sdk": "latest",
15
+ "dotenv": "latest"
16
+ },
17
+ "keywords": [
18
+ "mcp",
19
+ "mcp-server",
20
+ "alienmail"
21
+ ],
22
+ "author": "",
23
+ "license": "ISC"
24
+ }