@mailloom/mcp 0.1.0 → 0.1.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.
- package/README.md +82 -81
- package/dist/client.d.ts +4 -2
- package/dist/client.js +10 -4
- package/dist/index.js +24 -2
- package/package.json +53 -50
package/README.md
CHANGED
|
@@ -1,81 +1,82 @@
|
|
|
1
|
-
# @mailloom/mcp
|
|
2
|
-
|
|
3
|
-
Official [Model Context Protocol](https://modelcontextprotocol.io) server for [Mailloom](https://mailloom.app) — manage email templates, brand kits, and assets from Cursor, Claude, and other MCP hosts.
|
|
4
|
-
|
|
5
|
-
## Setup
|
|
6
|
-
|
|
7
|
-
1. Sign in to Mailloom → **Account settings**.
|
|
8
|
-
2. Ensure **Allow MCP / API write access** is on (default) if agents should mutate data.
|
|
9
|
-
3. **Create key** and copy the `ml_live_…` secret once.
|
|
10
|
-
|
|
11
|
-
API auth runs in the Supabase Edge Function `mailloom-api` (service role never leaves Supabase). Prefer the Next `/api/v1` base so `export_template` works; that route proxies CRUD to the edge function.
|
|
12
|
-
|
|
13
|
-
### Cursor (`mcp.json`)
|
|
14
|
-
|
|
15
|
-
```json
|
|
16
|
-
{
|
|
17
|
-
"mcpServers": {
|
|
18
|
-
"mailloom": {
|
|
19
|
-
"command": "npx",
|
|
20
|
-
"args": ["-y", "@mailloom/mcp"],
|
|
21
|
-
"env": {
|
|
22
|
-
"MAILLOOM_API_KEY": "ml_live_…",
|
|
23
|
-
"MAILLOOM_API_BASE": "
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
### Local package (unpublished)
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
cd packages/mailloom-mcp
|
|
37
|
-
npm install
|
|
38
|
-
npm run build
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
```json
|
|
42
|
-
{
|
|
43
|
-
"mcpServers": {
|
|
44
|
-
"mailloom": {
|
|
45
|
-
"command": "node",
|
|
46
|
-
"args": ["/absolute/path/to/packages/mailloom-mcp/dist/index.js"],
|
|
47
|
-
"env": {
|
|
48
|
-
"MAILLOOM_API_KEY": "ml_live_…",
|
|
49
|
-
"MAILLOOM_API_BASE": "http://localhost:3847/api/v1"
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## Environment
|
|
57
|
-
|
|
58
|
-
| Variable | Required | Default | Purpose |
|
|
59
|
-
| --- | --- | --- | --- |
|
|
60
|
-
| `MAILLOOM_API_KEY` | yes | — | `ml_live_…` from Account settings |
|
|
61
|
-
| `MAILLOOM_API_BASE` | no |
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
70
|
-
| `
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
73
|
-
| `
|
|
74
|
-
| `
|
|
75
|
-
| `
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
1
|
+
# @mailloom/mcp
|
|
2
|
+
|
|
3
|
+
Official [Model Context Protocol](https://modelcontextprotocol.io) server for [Mailloom](https://mailloom.app) — manage email templates, brand kits, and assets from Cursor, Claude, and other MCP hosts.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
1. Sign in to Mailloom → **Account settings**.
|
|
8
|
+
2. Ensure **Allow MCP / API write access** is on (default) if agents should mutate data.
|
|
9
|
+
3. **Create key** and copy the `ml_live_…` secret once.
|
|
10
|
+
|
|
11
|
+
API auth runs in the Supabase Edge Function `mailloom-api` (service role never leaves Supabase). Prefer the Next `/api/v1` base so `export_template` works; that route proxies CRUD to the edge function.
|
|
12
|
+
|
|
13
|
+
### Cursor (`mcp.json`)
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"mcpServers": {
|
|
18
|
+
"mailloom": {
|
|
19
|
+
"command": "npx",
|
|
20
|
+
"args": ["-y", "@mailloom/mcp"],
|
|
21
|
+
"env": {
|
|
22
|
+
"MAILLOOM_API_KEY": "ml_live_…",
|
|
23
|
+
"MAILLOOM_API_BASE": "https://<project>.supabase.co/functions/v1/mailloom-api",
|
|
24
|
+
"MAILLOOM_ANON_KEY": "<supabase-anon-key>"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Account settings copies this snippet for you. For HTML `export_template`, point `MAILLOOM_API_BASE` at your app `/api/v1` instead (proxies to the Edge Function).
|
|
32
|
+
|
|
33
|
+
### Local package (unpublished)
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
cd packages/mailloom-mcp
|
|
37
|
+
npm install
|
|
38
|
+
npm run build
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"mcpServers": {
|
|
44
|
+
"mailloom": {
|
|
45
|
+
"command": "node",
|
|
46
|
+
"args": ["/absolute/path/to/packages/mailloom-mcp/dist/index.js"],
|
|
47
|
+
"env": {
|
|
48
|
+
"MAILLOOM_API_KEY": "ml_live_…",
|
|
49
|
+
"MAILLOOM_API_BASE": "http://localhost:3847/api/v1"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Environment
|
|
57
|
+
|
|
58
|
+
| Variable | Required | Default | Purpose |
|
|
59
|
+
| --- | --- | --- | --- |
|
|
60
|
+
| `MAILLOOM_API_KEY` | yes | — | `ml_live_…` from Account settings |
|
|
61
|
+
| `MAILLOOM_API_BASE` | no | Mailloom Edge Function URL | Edge Function or Next `/api/v1` |
|
|
62
|
+
| `MAILLOOM_ANON_KEY` | for Edge Function | — | Public Supabase anon key (`apikey` header) |
|
|
63
|
+
|
|
64
|
+
## Tools
|
|
65
|
+
|
|
66
|
+
| Tool | Write? | Description |
|
|
67
|
+
| --- | --- | --- |
|
|
68
|
+
| `health_check` | | API liveness + write flag |
|
|
69
|
+
| `get_account` | | Email, write flag, key metadata |
|
|
70
|
+
| `list_templates` / `get_template` | | Templates (user + platform) |
|
|
71
|
+
| `create_template` / `update_template` / `duplicate_template` / `delete_template` | ✓ | Mutate user templates |
|
|
72
|
+
| `export_template` | | Render HTML (optional inline CSS) |
|
|
73
|
+
| `list_brand_kits` / `get_brand_kit` | | Brand kits |
|
|
74
|
+
| `create_brand_kit` / `update_brand_kit` / `delete_brand_kit` | ✓ | Mutate kits |
|
|
75
|
+
| `list_assets` | | Assets |
|
|
76
|
+
| `upload_asset` / `delete_asset` | ✓ | Upload (base64/url) / delete |
|
|
77
|
+
|
|
78
|
+
When write access is disabled in Account settings, write tools return `403 write_disabled`. Platform templates stay read-only; duplicate them to edit.
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
MIT
|
package/dist/client.d.ts
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
* Thin Mailloom API client for MCP.
|
|
3
3
|
* Auth: Authorization Bearer ml_live_…
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Default base is the mailloom-api Edge Function (no local Next required).
|
|
6
|
+
* Optional MAILLOOM_ANON_KEY (public) is sent as `apikey` for the Supabase gateway.
|
|
7
|
+
* For HTML export, point MAILLOOM_API_BASE at your app `/api/v1` instead.
|
|
7
8
|
*/
|
|
8
9
|
export type ApiConfig = {
|
|
9
10
|
baseUrl: string;
|
|
10
11
|
apiKey: string;
|
|
12
|
+
anonKey?: string;
|
|
11
13
|
};
|
|
12
14
|
export declare function loadConfig(): ApiConfig;
|
|
13
15
|
export declare function apiRequest(config: ApiConfig, method: string, path: string, opts?: {
|
package/dist/client.js
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
* Thin Mailloom API client for MCP.
|
|
3
3
|
* Auth: Authorization Bearer ml_live_…
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Default base is the mailloom-api Edge Function (no local Next required).
|
|
6
|
+
* Optional MAILLOOM_ANON_KEY (public) is sent as `apikey` for the Supabase gateway.
|
|
7
|
+
* For HTML export, point MAILLOOM_API_BASE at your app `/api/v1` instead.
|
|
7
8
|
*/
|
|
8
|
-
const DEFAULT_BASE = '
|
|
9
|
+
const DEFAULT_BASE = 'https://mailloom.partnerflow.co.za/api/v1';
|
|
9
10
|
export function loadConfig() {
|
|
10
11
|
const apiKey = (process.env.MAILLOOM_API_KEY || '').trim();
|
|
11
12
|
if (!apiKey) {
|
|
@@ -15,7 +16,8 @@ export function loadConfig() {
|
|
|
15
16
|
throw new Error('MAILLOOM_API_KEY must start with ml_live_');
|
|
16
17
|
}
|
|
17
18
|
const baseUrl = (process.env.MAILLOOM_API_BASE || DEFAULT_BASE).replace(/\/$/, '');
|
|
18
|
-
|
|
19
|
+
const anonKey = (process.env.MAILLOOM_ANON_KEY || '').trim() || undefined;
|
|
20
|
+
return { baseUrl, apiKey, anonKey };
|
|
19
21
|
}
|
|
20
22
|
export async function apiRequest(config, method, path, opts) {
|
|
21
23
|
const url = new URL(path.startsWith('http') ? path : `${config.baseUrl}${path.startsWith('/') ? path : `/${path}`}`);
|
|
@@ -30,6 +32,10 @@ export async function apiRequest(config, method, path, opts) {
|
|
|
30
32
|
Authorization: `Bearer ${config.apiKey}`,
|
|
31
33
|
Accept: 'application/json',
|
|
32
34
|
};
|
|
35
|
+
// Supabase Functions gateway expects the project anon key even when verify_jwt is off.
|
|
36
|
+
if (config.anonKey) {
|
|
37
|
+
headers.apikey = config.anonKey;
|
|
38
|
+
}
|
|
33
39
|
if (opts?.body !== undefined) {
|
|
34
40
|
headers['Content-Type'] = 'application/json';
|
|
35
41
|
}
|
package/dist/index.js
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
* Official Mailloom MCP server — templates, brand kits, assets for AI hosts.
|
|
4
4
|
*
|
|
5
5
|
* Env:
|
|
6
|
-
* MAILLOOM_API_KEY
|
|
7
|
-
* MAILLOOM_API_BASE
|
|
6
|
+
* MAILLOOM_API_KEY required — ml_live_…
|
|
7
|
+
* MAILLOOM_API_BASE optional — Edge Function URL (default) or Next /api/v1
|
|
8
|
+
* MAILLOOM_ANON_KEY optional — public Supabase anon key (needed for Edge Function)
|
|
8
9
|
*
|
|
9
10
|
* Write tools require Account settings → Allow MCP / API write access (default on).
|
|
10
11
|
* When disabled, mutating tools return 403 write_disabled; reads still work.
|
|
@@ -52,10 +53,31 @@ tool('update_template', 'Update a user template name and/or document. Platform t
|
|
|
52
53
|
name: z.string().optional().describe('New name'),
|
|
53
54
|
document: z.record(z.unknown()).optional().describe('Full email document'),
|
|
54
55
|
brand_kit_id: z.string().uuid().nullable().optional().describe('Brand kit UUID or null'),
|
|
56
|
+
publish_slug: z
|
|
57
|
+
.string()
|
|
58
|
+
.nullable()
|
|
59
|
+
.optional()
|
|
60
|
+
.describe('Public slug for external apps (null to unpublish)'),
|
|
55
61
|
}, async (args) => {
|
|
56
62
|
const { id, ...body } = args;
|
|
57
63
|
return apiRequest(config, 'PATCH', `/templates/${id}`, { body });
|
|
58
64
|
});
|
|
65
|
+
tool('publish_template', 'Set or clear publish_slug on a user template so external apps can fetch by slug. Requires write access.', {
|
|
66
|
+
id: z.string().uuid().describe('Template UUID'),
|
|
67
|
+
publish_slug: z
|
|
68
|
+
.string()
|
|
69
|
+
.nullable()
|
|
70
|
+
.describe('Slug like ytsgpt-welcome-1, or null to unpublish'),
|
|
71
|
+
}, async (args) => apiRequest(config, 'PATCH', `/templates/${args.id}`, {
|
|
72
|
+
body: { publish_slug: args.publish_slug },
|
|
73
|
+
}));
|
|
74
|
+
tool('get_template_by_slug', 'Get a published user template by publish_slug.', { slug: z.string().describe('Publish slug') }, async (args) => apiRequest(config, 'GET', `/templates/by-slug/${encodeURIComponent(String(args.slug))}`));
|
|
75
|
+
tool('export_template_by_slug', 'Export a published template as email HTML by slug. Read-only (via Next /api/v1).', {
|
|
76
|
+
slug: z.string().describe('Publish slug'),
|
|
77
|
+
inline: z.boolean().optional().describe('Inline CSS (default true)'),
|
|
78
|
+
}, async (args) => apiRequest(config, 'POST', `/templates/by-slug/${encodeURIComponent(String(args.slug))}/export`, {
|
|
79
|
+
body: { inline: args.inline },
|
|
80
|
+
}));
|
|
59
81
|
tool('duplicate_template', 'Copy a platform or user template into a new editable user template. Requires write access.', {
|
|
60
82
|
id: z.string().uuid().describe('Source template UUID'),
|
|
61
83
|
name: z.string().optional().describe('Name for the copy'),
|
package/package.json
CHANGED
|
@@ -1,50 +1,53 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@mailloom/mcp",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Official Mailloom MCP server — manage email templates, brand kits, and assets via the Mailloom API.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"mailloom-mcp": "bin/mailloom-mcp.js"
|
|
8
|
-
},
|
|
9
|
-
"main": "./dist/index.js",
|
|
10
|
-
"types": "./dist/index.d.ts",
|
|
11
|
-
"exports": {
|
|
12
|
-
".": {
|
|
13
|
-
"types": "./dist/index.d.ts",
|
|
14
|
-
"import": "./dist/index.js"
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"scripts": {
|
|
18
|
-
"build": "tsc -p tsconfig.json",
|
|
19
|
-
"start": "node dist/index.js",
|
|
20
|
-
"dev": "tsx src/index.ts",
|
|
21
|
-
"prepublishOnly": "npm run build"
|
|
22
|
-
},
|
|
23
|
-
"engines": {
|
|
24
|
-
"node": ">=18"
|
|
25
|
-
},
|
|
26
|
-
"dependencies": {
|
|
27
|
-
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
28
|
-
"zod": "^3.24.2"
|
|
29
|
-
},
|
|
30
|
-
"devDependencies": {
|
|
31
|
-
"@types/node": "^22.13.10",
|
|
32
|
-
"tsx": "^4.19.3",
|
|
33
|
-
"typescript": "^5.8.2"
|
|
34
|
-
},
|
|
35
|
-
"files": [
|
|
36
|
-
"bin",
|
|
37
|
-
"dist",
|
|
38
|
-
"README.md"
|
|
39
|
-
],
|
|
40
|
-
"keywords": [
|
|
41
|
-
"mailloom",
|
|
42
|
-
"mcp",
|
|
43
|
-
"model-context-protocol",
|
|
44
|
-
"cursor",
|
|
45
|
-
"claude",
|
|
46
|
-
"email",
|
|
47
|
-
"templates"
|
|
48
|
-
],
|
|
49
|
-
"
|
|
50
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@mailloom/mcp",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Official Mailloom MCP server — manage email templates, brand kits, and assets via the Mailloom API.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"mailloom-mcp": "bin/mailloom-mcp.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc -p tsconfig.json",
|
|
19
|
+
"start": "node dist/index.js",
|
|
20
|
+
"dev": "tsx src/index.ts",
|
|
21
|
+
"prepublishOnly": "npm run build"
|
|
22
|
+
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=18"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
28
|
+
"zod": "^3.24.2"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^22.13.10",
|
|
32
|
+
"tsx": "^4.19.3",
|
|
33
|
+
"typescript": "^5.8.2"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"bin",
|
|
37
|
+
"dist",
|
|
38
|
+
"README.md"
|
|
39
|
+
],
|
|
40
|
+
"keywords": [
|
|
41
|
+
"mailloom",
|
|
42
|
+
"mcp",
|
|
43
|
+
"model-context-protocol",
|
|
44
|
+
"cursor",
|
|
45
|
+
"claude",
|
|
46
|
+
"email",
|
|
47
|
+
"templates"
|
|
48
|
+
],
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public"
|
|
51
|
+
},
|
|
52
|
+
"license": "MIT"
|
|
53
|
+
}
|