groundmail-mcp 0.5.14 → 0.6.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/README.md CHANGED
@@ -55,7 +55,7 @@ When you connect, you choose the access: **Full**, **Send only** or **Read only*
55
55
  >
56
56
  > "How is my deliverability over the last 7 days?"
57
57
 
58
- Tools cover emails (send, schedule, cancel, look up), domains (add, apply DNS, verify), templates, webhooks, suppressions and deliverability. Each tool carries read-only and destructive annotations and an output schema. Full list: [docs.groundmail.dev/ai/mcp](https://docs.groundmail.dev/ai/mcp).
58
+ Tools cover emails (send, schedule, cancel, look up), domains (add, apply DNS, verify), templates, webhooks, suppressions and deliverability, plus importing your setup from SendGrid, Postmark or Mailgun (beta). Each tool carries read-only and destructive annotations and an output schema. Full list: [docs.groundmail.dev/ai/mcp](https://docs.groundmail.dev/ai/mcp).
59
59
 
60
60
  ## Transports
61
61
 
@@ -148,8 +148,13 @@ Want your coding agent to know Groundmail too? Install the [agent skills](https:
148
148
  | Laravel | [Groundmail/groundmail-laravel](https://github.com/Groundmail/groundmail-laravel) |
149
149
  | Symfony Mailer | [Groundmail/groundmail-symfony-mailer](https://github.com/Groundmail/groundmail-symfony-mailer) |
150
150
  | Nodemailer | [Groundmail/groundmail-nodemailer](https://github.com/Groundmail/groundmail-nodemailer) |
151
+ | NestJS | [Groundmail/nestjs-groundmail](https://github.com/Groundmail/nestjs-groundmail) |
152
+ | Strapi | [Groundmail/strapi-provider-email-groundmail](https://github.com/Groundmail/strapi-provider-email-groundmail) |
153
+ | Medusa | [Groundmail/medusa-notification-groundmail](https://github.com/Groundmail/medusa-notification-groundmail) |
154
+ | AdonisJS | [Groundmail/adonisjs-groundmail](https://github.com/Groundmail/adonisjs-groundmail) |
151
155
  | CLI | [`groundmail-cli`](https://www.npmjs.com/package/groundmail-cli) on npm |
152
156
  | MCP server (Claude, ChatGPT, Cursor) | [Groundmail/groundmail-mcp](https://github.com/Groundmail/groundmail-mcp) |
153
157
  | Agent skills and Claude Code plugin | [Groundmail/groundmail-skills](https://github.com/Groundmail/groundmail-skills) |
158
+ | Email templates (React Email, MJML, HTML) | [Groundmail/email-templates](https://github.com/Groundmail/email-templates) |
154
159
 
155
160
  [Website](https://groundmail.dev) · [Docs](https://docs.groundmail.dev) · [Pricing](https://groundmail.dev/pricing) · [Sign up free](https://app.groundmail.dev/signup)
package/dist/index.js CHANGED
@@ -346,6 +346,39 @@ var deliverabilityOutput = object(
346
346
  },
347
347
  ["window", "summary"]
348
348
  );
349
+ var anyObject = (description) => ({ type: "object", description });
350
+ var migrationOutput = object(
351
+ {
352
+ migration: described(
353
+ object(
354
+ {
355
+ id: string("Import id"),
356
+ provider: string("sendgrid, postmark or mailgun"),
357
+ dry_run: boolean("True for a preview: nothing was written"),
358
+ status: string("completed, partial (some items failed, each listed), failed, or in_progress"),
359
+ started_at: string("When the import started (ISO 8601)"),
360
+ resources: stringArray("What was imported: domains, webhooks, templates, suppressions"),
361
+ has_more: boolean("True if the import stopped early; call the tool again with `cursor` to continue"),
362
+ next_cursor: nullableString("Pass as `cursor` to continue an import that stopped early"),
363
+ retry_after_seconds: { type: ["number", "null"], description: "Wait this long before continuing" },
364
+ domains: anyObject("Totals and one item per domain, with the DNS records to publish"),
365
+ webhooks: anyObject("Totals and one item per webhook (created disabled), with mapped events and the signing secret"),
366
+ templates: anyObject("Totals and one item per template, with its alias and conversion notes"),
367
+ suppressions: anyObject("Totals by type (bounce, complaint, unsubscribe, manual) and skip reasons"),
368
+ errors: arrayOf(anyObject("A resource that could not be read"), "Resources that could not be read at all"),
369
+ notes: stringArray("What was left out on purpose, and why"),
370
+ attention: stringArray("What the user still needs to do"),
371
+ template_map: arrayOf(anyObject("Provider template id and Groundmail alias"), "Provider template id \u2192 Groundmail alias"),
372
+ code_changes: { type: ["array", "null"], items: anyObject("One stack"), description: "Send call before and after, for Node.js, Python and cURL" },
373
+ agent_prompt: nullableString("Prompt for a coding agent to make the code change")
374
+ },
375
+ ["id", "provider", "dry_run", "status", "has_more"]
376
+ ),
377
+ "The import report"
378
+ )
379
+ },
380
+ ["migration"]
381
+ );
349
382
 
350
383
  // src/tools.ts
351
384
  function textResult(value, isError = false) {
@@ -581,6 +614,27 @@ async function callMcpTool(client, name, args) {
581
614
  const result = await client.emails.insights(window);
582
615
  return textResult(result);
583
616
  }
617
+ case "import_from_provider": {
618
+ const provider = optString(args, "provider");
619
+ if (provider !== "sendgrid" && provider !== "postmark" && provider !== "mailgun") {
620
+ return textResult("Missing or unknown provider: use sendgrid, postmark or mailgun", true);
621
+ }
622
+ const apiKey = optString(args, "api_key");
623
+ if (!apiKey) return textResult("Missing required argument: api_key (the key of the account to import from)", true);
624
+ const region = optString(args, "region");
625
+ const resources = optStringArray(args, "resources");
626
+ const cursor = optString(args, "cursor");
627
+ const params = {
628
+ provider,
629
+ api_key: apiKey,
630
+ ...optString(args, "account_api_key") ? { account_api_key: optString(args, "account_api_key") } : {},
631
+ ...region === "us" || region === "eu" ? { region } : {},
632
+ ...resources?.length ? { resources } : {},
633
+ ...optBoolean(args, "dry_run") ? { dry_run: true } : {},
634
+ ...cursor ? { cursor } : {}
635
+ };
636
+ return textResult({ migration: await client.migrations.run(params) });
637
+ }
584
638
  default:
585
639
  return textResult(`Unknown tool: ${name}`, true);
586
640
  }
@@ -976,6 +1030,39 @@ var MCP_TOOLS = [
976
1030
  },
977
1031
  outputSchema: deliverabilityOutput,
978
1032
  annotations: readOnly("Get deliverability metrics")
1033
+ },
1034
+ {
1035
+ name: "import_from_provider",
1036
+ description: "Beta. Import templates, suppressions (bounces, complaints, unsubscribes), sending domains and webhooks from SendGrid, Postmark or Mailgun into Groundmail. Ask the user for their provider API key; it is used for this import only and never stored, so do not write it to a file. Run with dry_run first to show the user what will be imported. Imported webhooks start disabled; templates that use logic Groundmail does not convert are imported as drafts. The result includes what needs attention, the code change, and a prompt for making it.",
1037
+ inputSchema: {
1038
+ type: "object",
1039
+ properties: {
1040
+ provider: { type: "string", enum: ["sendgrid", "postmark", "mailgun"], description: "Provider to import from" },
1041
+ api_key: {
1042
+ type: "string",
1043
+ description: "SendGrid API key, Postmark server API token, or Mailgun private API key (read access is enough)"
1044
+ },
1045
+ account_api_key: { type: "string", description: "Postmark only: account API token, needed to import sending domains" },
1046
+ region: { type: "string", enum: ["us", "eu"], description: "SendGrid and Mailgun: eu for EU-region accounts (default us)" },
1047
+ resources: {
1048
+ type: "array",
1049
+ items: { type: "string", enum: ["domains", "webhooks", "templates", "suppressions"] },
1050
+ description: "What to import (default: all four)"
1051
+ },
1052
+ dry_run: { type: "boolean", description: "Preview without writing anything" },
1053
+ cursor: { type: "string", description: "next_cursor from an import that stopped early, to continue it" }
1054
+ },
1055
+ required: ["provider", "api_key"]
1056
+ },
1057
+ outputSchema: migrationOutput,
1058
+ // Re-running skips what already exists, so it is safe to repeat.
1059
+ annotations: {
1060
+ title: "Import from another provider",
1061
+ readOnlyHint: false,
1062
+ destructiveHint: false,
1063
+ idempotentHint: true,
1064
+ openWorldHint: true
1065
+ }
979
1066
  }
980
1067
  ];
981
1068
  function resolveApiKey() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "groundmail-mcp",
3
- "version": "0.5.14",
3
+ "version": "0.6.0",
4
4
  "mcpName": "io.github.Groundmail/groundmail",
5
5
  "description": "Groundmail MCP server: send transactional email, manage domains, templates, webhooks and suppressions from Claude, Cursor, ChatGPT and other MCP clients",
6
6
  "license": "MIT",
@@ -41,7 +41,7 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@modelcontextprotocol/sdk": "^1.30.0",
44
- "groundmail": "0.14.5"
44
+ "groundmail": "0.14.6"
45
45
  },
46
46
  "devDependencies": {
47
47
  "tsup": "^8.5.0",