Skip to content

v2.1.0

Choose a tag to compare

@coaldonac coaldonac released this 22 Jun 20:33
· 2 commits to main since this release
6697940

What's New

Added

  • Structured JSON logging to stderr. Every tool invocation emits a log line with { timestamp, tool, clientName, clientVersion, sanitizedArgs, status, durationMs }. Optional LOG_FILE env var additionally appends logs to a file for persistence and support escalation.
  • Email address masking in logs. PII-reduced by default — the mailbox is partially masked (first and last characters retained, middle replaced with length-proportional asterisks — e.g. alice@example.com → a***e@example.com), domain logged in full. Set LOG_EMAIL_FULL=true to disable masking.
  • MCP client identity capture. The initialize handshake captures the connecting client's name and version and attaches them to every log entry and outbound request header (X-Postmark-MCP-Client: <name>/<version>).
  • AGENT_LABEL env var and X-Agent-Label request header. Tag your MCP server instance with a label sent on every Postmark API request for traffic attribution.
  • MCP tool annotations. All 24 tools are annotated with readOnlyHint, destructiveHint, and idempotentHint so MCP clients can display risk indicators and gate destructive actions appropriately.
  • Tool descriptions. All 24 server.tool() registrations now include a concise description string, improving tool discovery and LLM decision-making.
  • sendEmail multi-recipient support. The to field now accepts either a single address string or an array of up to 50 addresses. Added optional cc, bcc, and replyTo fields.
  • sendEmailWithTemplate improvements. Added cc, bcc, and replyTo fields. Added a mutual-exclusivity guard: supplying both templateId and templateAlias now fails fast with a descriptive error.
  • Webhook URL allowlist (WEBHOOK_URL_ALLOWLIST). Set this env var to a comma-separated list of HTTPS URL prefixes; createWebhook will reject any URL that does not match.
  • Actionable startup error messages. Missing or invalid configuration now produces messages that name the env var, explain the consequence, and link to relevant Postmark documentation.
  • npx-based client configuration snippet in README. Covers Cursor, Claude Desktop, and Windsurf — no local clone required.
  • Automated test suite (52 tests across 3 tiers).
    • Tier 1 — Unit (npm test): 34 tests for maskEmail, sanitizeArgs, and writeLog in lib/log.js.
    • Tier 2 — Offline MCP validation (npm run test:offline): 11 tests covering webhook HTTPS enforcement, allowlist behavior, and tool annotation correctness — no Postmark account required.
    • Tier 3 — E2E env var wiring (npm run test:e2e): 7 tests verifying LOG_FILE, LOG_EMAIL_FULL, and MCP client identity capture end-to-end.
  • POSTMARK_SKIP_VERIFY env var. Bypasses the startup /server connectivity check; intended for test environments and offline use.

Changed

  • X-Postmark-Client correlation-id header replaced. The v2.0.0 header X-Postmark-Client: <version> / <uuid> has been replaced by two purpose-specific headers: X-Postmark-MCP-Client: <name>/<version> (MCP client identity) and X-Agent-Label: <value> (operator-supplied instance tag). If you built tooling to parse the old header format, update accordingly.
  • createWebhook now requires HTTPS. HTTP webhook URLs are rejected at the Zod schema level before any API call is made.
  • listTemplates response includes a truncation notice when exactly 100 templates are returned (API cap).
  • searchBounces and searchOutboundMessages document the 10,000 pagination cap.
  • deleteTemplate documentation notes Layout template constraints.
  • Logging extracted to lib/log.js. A createLogger factory is exported, making logging independently testable and reusable.
  • Dependencies pinned to exact versions (@modelcontextprotocol/sdk@1.29.0, dotenv@16.6.1, zod@3.25.76) to reduce supply chain risk.
  • package-lock.json is now committed so npm ci installs a reproducible, audited dependency tree.

What's Next (deferred to a future release)

  • getWebhook and editWebhook tools
  • createWebhook: postFirstOpenOnly, bounceIncludeContent, and spamIncludeContent parameters
  • CI test gating on pull requests
  • Async log writes for improved performance under burst load

Full Changelog: https://github.com/ActiveCampaign/postmark-mcp/blob/main/CHANGELOG.md