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/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);