solostack-mcp 0.1.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.
- package/LICENSE +21 -0
- package/README.md +213 -0
- package/dist/provisioner.mjs +24262 -0
- package/dist/worker.mjs +71220 -0
- package/llms.txt +80 -0
- package/package.json +57 -0
- package/src/db/schema.sql +31 -0
package/llms.txt
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# SoloStack — MCP Email Marketing Server
|
|
2
|
+
|
|
3
|
+
> Email marketing that your AI agent deploys and runs. MCP server on Cloudflare Workers.
|
|
4
|
+
|
|
5
|
+
## Endpoints
|
|
6
|
+
|
|
7
|
+
### Provisioner (local, stdio transport)
|
|
8
|
+
Connect via MCP stdio for provisioning and gateway proxy to deployed worker.
|
|
9
|
+
|
|
10
|
+
### Worker (remote, HTTP transport)
|
|
11
|
+
POST /mcp — Streamable HTTP MCP transport
|
|
12
|
+
Authorization: Bearer <SOLOSTACK_API_KEY>
|
|
13
|
+
Accept: application/json, text/event-stream
|
|
14
|
+
|
|
15
|
+
## Provisioning Tools
|
|
16
|
+
|
|
17
|
+
### provision_solostack
|
|
18
|
+
Create a complete email marketing stack on Cloudflare (Worker + D1 + secrets).
|
|
19
|
+
- cloudflare_api_token (string, required): CF API token with Workers + D1 permissions
|
|
20
|
+
- cloudflare_account_id (string, required): CF account ID
|
|
21
|
+
- resend_api_key (string, required): Resend API key
|
|
22
|
+
- worker_name (string, optional): Worker name (default: solostack-<random>)
|
|
23
|
+
- sending_domain (string, required): Domain to send from
|
|
24
|
+
- from_email (string, optional): From address (default: hello@<domain>)
|
|
25
|
+
|
|
26
|
+
### check_status
|
|
27
|
+
Check health and deployment info of the provisioned worker.
|
|
28
|
+
|
|
29
|
+
### setup_email_domain
|
|
30
|
+
Add a sending domain to Resend. Returns DNS records to add.
|
|
31
|
+
- sending_domain (string, required): Domain to send from
|
|
32
|
+
- resend_api_key (string, optional): Reads from config if omitted
|
|
33
|
+
|
|
34
|
+
### verify_email_domain
|
|
35
|
+
Poll Resend until domain is verified. Auto-registers webhook on success.
|
|
36
|
+
- domain_id (string, optional): Reads from config if omitted
|
|
37
|
+
- max_attempts (number, optional): Polling attempts at 30s intervals (default: 10)
|
|
38
|
+
|
|
39
|
+
### migrate_subscribers
|
|
40
|
+
Import subscribers from CSV data.
|
|
41
|
+
- csv_data (string, required): CSV with email column + optional name, tags columns
|
|
42
|
+
|
|
43
|
+
### upgrade_solostack
|
|
44
|
+
Upload new worker bundle. Rolls back on health failure.
|
|
45
|
+
|
|
46
|
+
## Email Tools (proxied to deployed worker)
|
|
47
|
+
|
|
48
|
+
### subscribe
|
|
49
|
+
Add or re-activate a subscriber. Idempotent.
|
|
50
|
+
- email (string, required): Subscriber email
|
|
51
|
+
- source (string, optional): Signup source
|
|
52
|
+
- tags (string[], optional): Tags to apply
|
|
53
|
+
|
|
54
|
+
### unsubscribe
|
|
55
|
+
Mark a subscriber as unsubscribed.
|
|
56
|
+
- email (string, required): Email to unsubscribe
|
|
57
|
+
|
|
58
|
+
### list_subscribers
|
|
59
|
+
List subscribers with filtering.
|
|
60
|
+
- status (enum, optional): active | unsubscribed | bounced (default: active)
|
|
61
|
+
- tag (string, optional): Filter by tag
|
|
62
|
+
- limit (number, optional): Max results 1-500 (default: 50)
|
|
63
|
+
- offset (number, optional): Pagination offset (default: 0)
|
|
64
|
+
|
|
65
|
+
### get_subscriber_count
|
|
66
|
+
Count subscribers.
|
|
67
|
+
- status (enum, optional): active | unsubscribed | bounced (default: active)
|
|
68
|
+
- tag (string, optional): Filter by tag
|
|
69
|
+
|
|
70
|
+
### send_email
|
|
71
|
+
Send a single email via Resend.
|
|
72
|
+
- to (string, required): Recipient email
|
|
73
|
+
- subject (string, required): Subject line
|
|
74
|
+
- html (string, required): HTML body
|
|
75
|
+
|
|
76
|
+
### send_broadcast
|
|
77
|
+
Send to all active subscribers (max 100).
|
|
78
|
+
- subject (string, required): Subject line
|
|
79
|
+
- html (string, required): HTML body
|
|
80
|
+
- tag (string, optional): Filter recipients by tag
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "solostack-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for solo founder email marketing — subscriber management, email sending, broadcasts, analytics. Zero dashboards.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"solostack": "dist/provisioner.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist/provisioner.mjs",
|
|
11
|
+
"dist/worker.mjs",
|
|
12
|
+
"src/db/schema.sql",
|
|
13
|
+
"llms.txt",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"dev": "wrangler dev",
|
|
19
|
+
"deploy": "wrangler deploy",
|
|
20
|
+
"build": "tsx scripts/build-provisioner.ts && tsx scripts/build-bundle.ts",
|
|
21
|
+
"build:provisioner": "tsx scripts/build-provisioner.ts",
|
|
22
|
+
"build:bundle": "tsx scripts/build-bundle.ts",
|
|
23
|
+
"test:bundle": "tsx scripts/test-bundle.ts",
|
|
24
|
+
"test:e2e": "tsx scripts/e2e-test.ts",
|
|
25
|
+
"prepublishOnly": "npm run build",
|
|
26
|
+
"db:local": "wrangler d1 execute solostack --local --file=src/db/schema.sql",
|
|
27
|
+
"db:remote": "wrangler d1 execute solostack --remote --file=src/db/schema.sql"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
31
|
+
"agents": "^0.7.5",
|
|
32
|
+
"zod": "^3.24.2"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@cloudflare/workers-types": "^4.20260310.1",
|
|
36
|
+
"esbuild": "^0.27.4",
|
|
37
|
+
"tsx": "^4.19.0",
|
|
38
|
+
"typescript": "^5.7.3",
|
|
39
|
+
"wrangler": "^4.71.0"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"mcp",
|
|
43
|
+
"email-marketing",
|
|
44
|
+
"cloudflare-workers",
|
|
45
|
+
"solo-founder",
|
|
46
|
+
"ai-agent",
|
|
47
|
+
"model-context-protocol"
|
|
48
|
+
],
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "https://github.com/stue/solostack.git"
|
|
53
|
+
},
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=18"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
-- SoloStack D1 Schema — Tier 1 MVP
|
|
2
|
+
|
|
3
|
+
CREATE TABLE IF NOT EXISTS subscribers (
|
|
4
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
5
|
+
email TEXT UNIQUE NOT NULL COLLATE NOCASE,
|
|
6
|
+
source TEXT,
|
|
7
|
+
tags TEXT DEFAULT '[]',
|
|
8
|
+
status TEXT DEFAULT 'active' CHECK (status IN ('active', 'unsubscribed', 'bounced')),
|
|
9
|
+
subscribed_at TEXT DEFAULT (datetime('now')),
|
|
10
|
+
unsubscribed_at TEXT
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
CREATE INDEX IF NOT EXISTS idx_subscribers_status ON subscribers(status);
|
|
14
|
+
CREATE INDEX IF NOT EXISTS idx_subscribers_email ON subscribers(email);
|
|
15
|
+
|
|
16
|
+
CREATE TABLE IF NOT EXISTS email_log (
|
|
17
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
18
|
+
subscriber_id INTEGER,
|
|
19
|
+
resend_id TEXT,
|
|
20
|
+
subject TEXT,
|
|
21
|
+
type TEXT DEFAULT 'transactional' CHECK (type IN ('broadcast', 'drip', 'transactional')),
|
|
22
|
+
status TEXT DEFAULT 'sent' CHECK (status IN ('sent', 'delivered', 'opened', 'clicked', 'bounced', 'complained')),
|
|
23
|
+
sent_at TEXT DEFAULT (datetime('now')),
|
|
24
|
+
delivered_at TEXT,
|
|
25
|
+
opened_at TEXT,
|
|
26
|
+
clicked_at TEXT,
|
|
27
|
+
FOREIGN KEY (subscriber_id) REFERENCES subscribers(id)
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
CREATE INDEX IF NOT EXISTS idx_email_log_resend_id ON email_log(resend_id);
|
|
31
|
+
CREATE INDEX IF NOT EXISTS idx_email_log_subscriber ON email_log(subscriber_id);
|