supersendtx-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.
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/server.ts
4
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
5
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
+ import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
7
+ import { SuperSendTX } from "supersendtx";
8
+
9
+ // src/tools.ts
10
+ function textResult(value, isError = false) {
11
+ return {
12
+ content: [{ type: "text", text: typeof value === "string" ? value : JSON.stringify(value, null, 2) }],
13
+ ...isError ? { isError: true } : {}
14
+ };
15
+ }
16
+ async function callMcpTool(client, name, args) {
17
+ try {
18
+ switch (name) {
19
+ case "send_email": {
20
+ const result = await client.emails.send({
21
+ from: String(args.from),
22
+ to: String(args.to),
23
+ subject: String(args.subject),
24
+ html: args.html != null ? String(args.html) : void 0,
25
+ text: args.text != null ? String(args.text) : void 0,
26
+ reply_to: args.reply_to != null ? String(args.reply_to) : void 0
27
+ });
28
+ return textResult(result);
29
+ }
30
+ case "apply_domain_dns": {
31
+ const domain = String(args.domain ?? "").trim();
32
+ if (!domain) {
33
+ return textResult("Missing required argument: domain", true);
34
+ }
35
+ const providerRaw = typeof args.provider === "string" ? args.provider.trim().toLowerCase() : "";
36
+ if (providerRaw !== "cloudflare" && providerRaw !== "godaddy") {
37
+ return textResult(
38
+ 'Missing or invalid provider. Use provider "cloudflare" or "godaddy".',
39
+ true
40
+ );
41
+ }
42
+ const credentials = args.credentials && typeof args.credentials === "object" ? args.credentials : void 0;
43
+ const result = await client.domains.apply(domain, {
44
+ provider: providerRaw,
45
+ ...credentials ? { credentials } : {}
46
+ });
47
+ return textResult(result);
48
+ }
49
+ case "verify_domain": {
50
+ const result = await client.domains.verify(String(args.domain));
51
+ return textResult(result);
52
+ }
53
+ case "get_deliverability": {
54
+ const window = args.window === "7d" ? "7d" : "30d";
55
+ const result = await client.emails.insights(window);
56
+ return textResult(result);
57
+ }
58
+ default:
59
+ return textResult(`Unknown tool: ${name}`, true);
60
+ }
61
+ } catch (error) {
62
+ const message = error && typeof error === "object" && "message" in error ? String(error.message) : "Request failed";
63
+ return textResult(message, true);
64
+ }
65
+ }
66
+ var MCP_TOOLS = [
67
+ {
68
+ name: "send_email",
69
+ description: "Send a transactional email via SuperSend TX. Sandbox sends must use the shared sandbox from address and only deliver to the account email until a domain is verified.",
70
+ inputSchema: {
71
+ type: "object",
72
+ properties: {
73
+ from: { type: "string", description: "Sender address (must match a verified domain or sandbox sender)" },
74
+ to: { type: "string", description: "Recipient email address" },
75
+ subject: { type: "string" },
76
+ html: { type: "string" },
77
+ text: { type: "string" },
78
+ reply_to: { type: "string" }
79
+ },
80
+ required: ["from", "to", "subject"]
81
+ }
82
+ },
83
+ {
84
+ name: "apply_domain_dns",
85
+ description: "Apply SuperSend TX DNS records for a domain. Cloudflare can use a token stored in the dashboard; GoDaddy accepts one-time credentials on the request.",
86
+ inputSchema: {
87
+ type: "object",
88
+ properties: {
89
+ domain: { type: "string" },
90
+ provider: { type: "string", enum: ["cloudflare", "godaddy"] },
91
+ credentials: {
92
+ type: "object",
93
+ description: "Optional inline registrar credentials (GoDaddy api key/secret)"
94
+ }
95
+ },
96
+ required: ["domain", "provider"]
97
+ }
98
+ },
99
+ {
100
+ name: "verify_domain",
101
+ description: "Verify DNS for a sending domain after records are applied.",
102
+ inputSchema: {
103
+ type: "object",
104
+ properties: {
105
+ domain: { type: "string" }
106
+ },
107
+ required: ["domain"]
108
+ }
109
+ },
110
+ {
111
+ name: "get_deliverability",
112
+ description: "Fetch best-effort deliverability metrics for recent sends (7d or 30d window).",
113
+ inputSchema: {
114
+ type: "object",
115
+ properties: {
116
+ window: { type: "string", enum: ["7d", "30d"] }
117
+ }
118
+ }
119
+ }
120
+ ];
121
+ function resolveApiKey() {
122
+ const key = process.env.SUPERSENDTX_API_KEY?.trim();
123
+ if (!key) {
124
+ throw new Error("SUPERSENDTX_API_KEY is required");
125
+ }
126
+ if (!key.startsWith("stx_")) {
127
+ throw new Error("SUPERSENDTX_API_KEY must start with stx_");
128
+ }
129
+ return key;
130
+ }
131
+
132
+ // src/server.ts
133
+ function createMcpServer(apiKey, baseUrl) {
134
+ const client = new SuperSendTX(apiKey, baseUrl ? { baseUrl } : {});
135
+ const server = new Server(
136
+ { name: "supersendtx-mcp", version: "0.1.0" },
137
+ { capabilities: { tools: {} } }
138
+ );
139
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
140
+ tools: MCP_TOOLS.map((tool) => ({
141
+ name: tool.name,
142
+ description: tool.description,
143
+ inputSchema: tool.inputSchema
144
+ }))
145
+ }));
146
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
147
+ const result = await callMcpTool(client, request.params.name, request.params.arguments ?? {});
148
+ return result;
149
+ });
150
+ return server;
151
+ }
152
+ async function runStdioServer() {
153
+ const apiKey = resolveApiKey();
154
+ const baseUrl = process.env.SUPERSENDTX_API_URL?.trim();
155
+ const server = createMcpServer(apiKey, baseUrl || void 0);
156
+ const transport = new StdioServerTransport();
157
+ await server.connect(transport);
158
+ }
159
+
160
+ // src/index.ts
161
+ runStdioServer().catch((error) => {
162
+ console.error(error instanceof Error ? error.message : error);
163
+ process.exit(1);
164
+ });
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "supersendtx-mcp",
3
+ "version": "0.1.0",
4
+ "description": "SuperSend TX MCP server — send email and manage domains from Cursor or Claude",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "supersendtx-mcp": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/Super-Send/superTX-app.git",
16
+ "directory": "packages/supersendtx-mcp"
17
+ },
18
+ "homepage": "https://docs.supersendtx.com/ai/mcp",
19
+ "keywords": [
20
+ "mcp",
21
+ "email",
22
+ "transactional",
23
+ "supersendtx",
24
+ "cursor",
25
+ "claude"
26
+ ],
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "engines": {
31
+ "node": ">=18"
32
+ },
33
+ "scripts": {
34
+ "build": "tsup",
35
+ "test": "vitest run",
36
+ "typecheck": "tsc --noEmit",
37
+ "prepublishOnly": "npm run build"
38
+ },
39
+ "dependencies": {
40
+ "@modelcontextprotocol/sdk": "^1.30.0",
41
+ "supersendtx": "0.8.0"
42
+ },
43
+ "devDependencies": {
44
+ "tsup": "^8.5.0",
45
+ "typescript": "^5",
46
+ "vitest": "^3.2.4"
47
+ }
48
+ }