io.github.cyanheads/mailchimp-mcp-server

Official registry Other

Mailchimp via MCP: draft, test, and send campaigns; manage audiences and subscribers; pull reports.

What can you do with io.github.cyanheads/mailchimp-mcp-server?

  • Marketing API v3 client that derives the API host and data center from the key's -<dc> suffix, with retries, a process-wide concurrency limit (MAILCHIMP_CONCURRENCY_LIMIT), and a cooldown after a 429
  • Send gates: campaigns default to draft, send / schedule need confirmSend: true plus a confirmation prompt, and new or resumed subscribed subscriptions need confirmation too; imports default to pending
  • No irreversible deletes: removing audiences, merge fields, or campaigns, and permanently deleting subscribers, stay in the Mailchimp UI; archive is the strongest subscriber removal
  • Local authoring: @assets/<path> files upload and rewrite at send time, and .eta templates render locally, which covers free plans where the Templates API is read-only
  • List operations page with count (max 1000) and offset
  • Explained empties: note / notes[] on empty activity feeds, audience overviews, and searches say whether data is missing or genuinely zero
  • Partial failure: mailchimp_import_subscribers and mailchimp_segments batch-update-members return per-row successes and errors instead of failing the batch
  • Discriminated outputs: operation, dimension, and mode say which fields are populated; isNew and cancelledByUser report what actually happened

Install

Add this to your client's MCP configuration (Claude Desktop: claude_desktop_config.json; Cursor: .cursor/mcp.json; VS Code and others use the same "mcpServers" shape).

NPM package @cyanheads/mailchimp-mcp-server
Claude Code
claude mcp add mailchimp-mcp-server -e 'MAILCHIMP_API_KEY=<MAILCHIMP_API_KEY>' -e 'MAILCHIMP_BASE_URL=<MAILCHIMP_BASE_URL>' -e 'MAILCHIMP_TIMEOUT_MS=60000' -e 'MAILCHIMP_MAX_RETRIES=3' -e 'MAILCHIMP_CONCURRENCY_LIMIT=4' -e 'MAILCHIMP_ASSETS_DIR=<MAILCHIMP_ASSETS_DIR>' -e 'MAILCHIMP_TEMPLATES_DIR=<MAILCHIMP_TEMPLATES_DIR>' -e 'MCP_LOG_LEVEL=info' -- npx -y @cyanheads/mailchimp-mcp-server@0.6.0
JSON configuration (Claude Desktop, Cursor, VS Code)
{
    "mcpServers": {
        "mailchimp-mcp-server": {
            "command": "npx",
            "args": [
                "-y",
                "@cyanheads/mailchimp-mcp-server@0.6.0"
            ],
            "env": {
                "MAILCHIMP_API_KEY": "<MAILCHIMP_API_KEY>",
                "MAILCHIMP_BASE_URL": "<MAILCHIMP_BASE_URL>",
                "MAILCHIMP_TIMEOUT_MS": "60000",
                "MAILCHIMP_MAX_RETRIES": "3",
                "MAILCHIMP_CONCURRENCY_LIMIT": "4",
                "MAILCHIMP_ASSETS_DIR": "<MAILCHIMP_ASSETS_DIR>",
                "MAILCHIMP_TEMPLATES_DIR": "<MAILCHIMP_TEMPLATES_DIR>",
                "MCP_LOG_LEVEL": "info"
            }
        }
    }
}

Environment variables

  • MAILCHIMP_API_KEY required Mailchimp Marketing API key, including the '-dc' data-center suffix (e.g. 'abc...-us22'). Generate at Mailchimp → Account → Extras → API keys.
  • MAILCHIMP_BASE_URL Override the API base URL (for mock servers or testing). Defaults to 'https://{dc}.api.mailchimp.com/3.0' derived from the API key suffix.
  • MAILCHIMP_TIMEOUT_MS Per-request timeout in milliseconds.
  • MAILCHIMP_MAX_RETRIES Max retry attempts for transient upstream failures (0-10).
  • MAILCHIMP_CONCURRENCY_LIMIT Max in-flight upstream requests across this process (1-10).
  • MAILCHIMP_ASSETS_DIR Absolute path to a local assets directory. When set (Node-only — Workers ignored), enables the `mailchimp_assets` tool and auto-uploads `@assets/<path>` references in campaign HTML to Mailchimp File Manager at send time. Cache at <dir>/.mailchimp-cache.json.
  • MAILCHIMP_TEMPLATES_DIR Absolute path to a local templates directory. When set (Node-only), enables the `mailchimp_local_templates` tool and support for `content.localTemplate` on campaign tools. Templates are `.eta` files with optional YAML frontmatter; legacy `<name>.meta.yaml` sidecars are read when frontmatter is absent. Canonical write path on free-tier Mailchimp.
  • MCP_LOG_LEVEL Minimum log level for output: debug, info, notice, warning, or error.
NPM package @cyanheads/mailchimp-mcp-server
Claude Code
claude mcp add mailchimp-mcp-server -e 'MCP_TRANSPORT_TYPE=<MCP_TRANSPORT_TYPE>' -e 'MAILCHIMP_API_KEY=<MAILCHIMP_API_KEY>' -e 'MAILCHIMP_BASE_URL=<MAILCHIMP_BASE_URL>' -e 'MAILCHIMP_TIMEOUT_MS=60000' -e 'MAILCHIMP_MAX_RETRIES=3' -e 'MAILCHIMP_CONCURRENCY_LIMIT=4' -e 'MCP_HTTP_HOST=127.0.0.1' -e 'MCP_HTTP_PORT=3010' -e 'MCP_HTTP_ENDPOINT_PATH=/mcp' -e 'MCP_AUTH_MODE=none' -e 'MCP_LOG_LEVEL=info' -- npx -y @cyanheads/mailchimp-mcp-server@0.6.0
JSON configuration (Claude Desktop, Cursor, VS Code)
{
    "mcpServers": {
        "mailchimp-mcp-server": {
            "command": "npx",
            "args": [
                "-y",
                "@cyanheads/mailchimp-mcp-server@0.6.0"
            ],
            "env": {
                "MCP_TRANSPORT_TYPE": "<MCP_TRANSPORT_TYPE>",
                "MAILCHIMP_API_KEY": "<MAILCHIMP_API_KEY>",
                "MAILCHIMP_BASE_URL": "<MAILCHIMP_BASE_URL>",
                "MAILCHIMP_TIMEOUT_MS": "60000",
                "MAILCHIMP_MAX_RETRIES": "3",
                "MAILCHIMP_CONCURRENCY_LIMIT": "4",
                "MCP_HTTP_HOST": "127.0.0.1",
                "MCP_HTTP_PORT": "3010",
                "MCP_HTTP_ENDPOINT_PATH": "/mcp",
                "MCP_AUTH_MODE": "none",
                "MCP_LOG_LEVEL": "info"
            }
        }
    }
}

Environment variables

  • MCP_TRANSPORT_TYPE Selects the HTTP transport.
  • MAILCHIMP_API_KEY required Mailchimp Marketing API key, including the '-dc' data-center suffix (e.g. 'abc...-us22'). Generate at Mailchimp → Account → Extras → API keys.
  • MAILCHIMP_BASE_URL Override the API base URL (for mock servers or testing). Defaults to 'https://{dc}.api.mailchimp.com/3.0' derived from the API key suffix.
  • MAILCHIMP_TIMEOUT_MS Per-request timeout in milliseconds.
  • MAILCHIMP_MAX_RETRIES Max retry attempts for transient upstream failures (0-10).
  • MAILCHIMP_CONCURRENCY_LIMIT Max in-flight upstream requests across this process (1-10).
  • MCP_HTTP_HOST The hostname for the HTTP server.
  • MCP_HTTP_PORT The port to run the HTTP server on.
  • MCP_HTTP_ENDPOINT_PATH The endpoint path for the MCP server.
  • MCP_AUTH_MODE Authentication mode to use: 'none', 'jwt', or 'oauth'.
  • MCP_LOG_LEVEL Minimum log level for output: debug, info, notice, warning, or error.

Documentation

From the project's README on GitHub, refreshed weekly. Links open on GitHub.

Contents
  1. @cyanheads/mailchimp-mcp-server
  2. Overview
  3. Capability reference
  4. Features
  5. Getting started
  6. Configuration
  7. Running the server
  8. Project structure
  9. Development guide
  10. Contributing
  11. License

@cyanheads/mailchimp-mcp-server

Draft, test, and send Mailchimp campaigns straight from your MCP client — with audience management, subscriber CRUD, and post-send analytics behind safe-by-default send gates. STDIO or Streamable HTTP.

18 Tools (+2 conditional) • 4 Resources • 1 Prompt


Overview

Mailchimp campaign management. Draft, test, and send email campaigns, manage audiences and subscribers, and review post-send analytics, with optional local image and template directories for authoring.

Tools
ToolDescription
mailchimp_accountAccount profile, plan, data center, and the Chimp Chatter activity feed
mailchimp_audiencesRead, create, and update audiences (lists), with per-audience analytics and signup-form config
mailchimp_audience_overviewOne-call audience digest: info, stats, growth history, top email clients, merge-field schema
mailchimp_subscribersSubscriber reads, updates, archive, tags, notes, and engagement history
mailchimp_upsert_subscriberAdd or update one subscriber idempotently, with status, merge fields, tags, and a note
mailchimp_find_subscriberLocate a subscriber by email in one audience or across the account
mailchimp_import_subscribersBatch add or update up to 500 subscribers per call, pending by default
mailchimp_segmentsSegment CRUD (saved, static, fuzzy), member listing, and batch add/remove
mailchimp_merge_fieldsRead, create, and update custom subscriber attributes
mailchimp_campaignsCampaign records, content, send checklist, and RSS/resend controls
mailchimp_send_campaignCompose a campaign and leave it as a draft, test it, send it, or schedule it in one call
mailchimp_replicate_campaignDuplicate a campaign with overrides, then draft, test, send, or schedule
mailchimp_reportsCampaign reports: the index, one report, or one of ten report dimensions
mailchimp_campaign_reportPost-send digest: headline metrics plus top links, locations, and unsubscribes
mailchimp_templatesMailchimp-hosted templates; reads work on free plans, writes need a paid plan
mailchimp_filesFile Manager uploads, listing, renames, and deletes on Mailchimp's CDN
mailchimp_searchSearch members or campaigns across the account
mailchimp_assets (conditional: MAILCHIMP_ASSETS_DIR)Inspect and pre-warm uploads for @assets/<path> references in campaign HTML
mailchimp_local_templates (conditional: MAILCHIMP_TEMPLATES_DIR)Author and render local .eta templates, the template write path on free plans
mailchimp_playbookProcedural playbooks merged with live account state; advice only
Resources
ResourceDescription
mailchimp://accountAccount snapshot: profile, plan, data center, total subscribers
mailchimp://audiences/{audienceId}Audience snapshot: name, contact, stats, double opt-in status
mailchimp://campaigns/{campaignId}Campaign snapshot: status, settings, recipients
mailchimp://campaigns/{campaignId}/reportPost-send headline metrics for a campaign

All resource data is also reachable through tools; audiences and campaigns are listed with each tool's list operation.

Prompts
PromptDescription
newsletter_from_sourceCompose an editorial newsletter from a URL or brief, then walk it through draft, test, and send

Design reference: docs/email-design-playbook.md.

Capability reference

mailchimp_account tool
  • operation: info returns profile, plan, data center, total subscribers, and industry benchmarks; operation: activity-feed returns Chimp Chatter events, paged by count (max 100, default 20) and offset
  • An empty activity feed carries a note naming the likely causes

mailchimp_audiences tool
  • Operations: list, get, create, update, the analytics reads list-activity, list-growth, list-clients, list-abuse-reports, list-locations, and get-signup-forms / customize-signup-forms (takes signupFormConfig); every operation except list and create needs audienceId
  • create requires name, contact (company, address1, city, state, zip, country), permissionReminder, and campaignDefaults (fromName, fromEmail, language)

mailchimp_audience_overview tool
  • audienceId plus growthMonths (1–36, default 12); returns info, stats, contact, campaign defaults, growth history, top email clients, and the merge-field schema
  • notes[] explains empty growth or email-client arrays, separating "no data yet" from zero engagement

mailchimp_subscribers tool
  • audienceId on every call and email on every operation except list (filterable by status); operations: list, get, update, archive, list-tags, set-tags, list-notes / add-note / update-note / delete-note (by noteId), and list-activity / list-events / list-goals
  • Addresses are trimmed and rejected if the local or domain part is missing; an empty list email stays unfiltered. update to subscribed asks for confirmation when resuming a subscription; already-subscribed members are left as they are
  • set-tags is declarative: tags becomes the full active set and every other tag is removed unless named in preserveTags (static-segment membership is stored as a tag). Returns tagsAdded, tagsRemoved, and tagsActive

mailchimp_upsert_subscriber tool
  • audienceId, email, and status required; optional mergeFields, tags + preserveTags (same declarative sync as set-tags), note, vip, language; updateExistingStatus: false applies status to new records only
  • Returns isNew, the resulting status, tagsAdded / tagsRemoved / tagsFinal, noteAttached, and webUrl
  • status: "pending" uses Mailchimp's double opt-in flow. New or resumed subscribed status asks for confirmation of documented consent before anything is written; declining writes nothing. Already-subscribed updates and updateExistingStatus: false keep the existing status without asking

mailchimp_find_subscriber tool
  • email accepts an address or free-form search fragment, including a fragment without @, scoped to one audienceId or, when omitted, every audience on the account (echoed as searchedAcross)
  • Returns exactMatches and fuzzyMatches with merge fields and stats; includeTags (default true) adds each match's tags at one extra call per match

mailchimp_import_subscribers tool
  • audienceId and 1–500 subscribers rows per call; status defaults to pending (double opt-in) and a per-row status overrides it; updateExisting defaults to false, so existing records are skipped
  • Any row that would be subscribed needs one confirmation before the whole batch writes; declining writes nothing. Pending-only imports need none
  • Returns totalCreated, totalUpdated, errorCount, and per-row succeeded and failed entries; incomplete addresses fail as invalid_email, and a batch with no valid rows makes no upstream request

mailchimp_segments tool
  • audienceId on every call and segmentId on every operation except list (filterable by type: saved, static, fuzzy) and create; create / update take name, staticEmails, or saved-segment options
  • batch-update-members applies membersToAdd / membersToRemove to a static segment and returns added, removed, and per-email errors
  • Free plans get static and basic saved segments; advanced conditions need Premium and fail as mailchimp_forbidden

mailchimp_merge_fields tool
  • list, get, create, update; create requires name, tag (10 characters max), and type; get / update take mergeId
  • options carries type-specific config: choices for dropdown / radio, date_format for date / birthday, phone_format for phone

mailchimp_campaigns tool
  • Operations: list (filter by status, listId, sinceSendTime / beforeSendTime), get, create (type of regular / plaintext / rss, plus recipients and settings), update, replicate, get-content, set-content, get-checklist, cancel-send, create-resend, pause-rss, resume-rss; all but list and create take campaignId
  • set-content accepts html, plainText, templateId + templateSections, archiveContent, url, or localTemplate (exclusive with html and templateId); get-checklist returns isReady and typed items
  • get-content accepts variant: html | plainText | archiveHtml | all (default all); empty bodies are omitted
  • No send, test, schedule, or delete here; dispatch goes through mailchimp_send_campaign or mailchimp_replicate_campaign

mailchimp_send_campaign tool
  • audienceId, subject, fromName, replyTo, and content (at least one of html, plainText, templateId, localTemplate) required; mode is draft (default), test (needs testEmails, max 50), send, or schedule (needs scheduleTime at least 15 minutes out)
  • Returns campaignId, the effective mode, status, recipientCount, webUrl, and non-blocking checklistWarnings; blocking checklist errors throw pre_send_checklist_failed outside draft, and cleanupOnError (default true) deletes the draft after a mid-flow failure
  • send and schedule require confirmSend: true, then a single-use confirmation prompt before any campaign is created; declining leaves a draft and sets cancelledByUser. Changed content or a replay asks again, and creation is never retried after an ambiguous upstream failure

mailchimp_replicate_campaign tool
  • sourceCampaignId plus optional subjectOverride, previewTextOverride, fromNameOverride, replyToOverride, titleOverride, audienceOverride, segmentOverride, and contentOverride; mode, testEmails, scheduleTime, and cleanupOnError work as in mailchimp_send_campaign
  • Returns the new campaignId, overridesApplied[], and the same status, checklist, and cancelledByUser fields
  • Same confirmSend: true plus confirmation-prompt gate for send and schedule

mailchimp_reports tool
  • list (filter by type, sinceSendTime / beforeSendTime), get, or slice with a campaignId and a dimension: abuse-reports, advice, click-details (one URL via linkId), open-details (one member via subscriberHash), domain-performance, eepurl, email-activity, locations, sent-to, unsubscribed
  • slice returns rows shaped by the dimension plus totalItems; get throws campaign_not_sent for a campaign with no send

mailchimp_campaign_report tool
  • campaignId plus includeTopN (1–100, default 10) rows per slice
  • Returns delivery (delivered, bounces by type, abuse reports), engagement (opens, clicks, unsubscribes), topClickedLinks, topLocations, recentUnsubscribes, and industryBenchmarks when Mailchimp has them; throws campaign_not_sent for a campaign with no send

mailchimp_templates tool
  • list (filter by type of user / base / gallery, category, folderId), get, get-default-content, create, update, and delete; update accepts only name, html, and folderId, so per-section edits go through a campaign's templateSections
  • Reads of base and user templates work on free plans; writes and gallery reads need a paid plan and fail as mailchimp_forbidden. mailchimp_local_templates is the authoring path on every plan

mailchimp_files tool
  • list (filter by type, folderId, sinceCreatedAt / beforeCreatedAt), get, upload (name with extension plus base64 fileData, no data: prefix), update (rename, or move with folderId, 0 for root), delete, and read-only list-folders / get-folder; uploads cap at 1 MB per image and 10 MB per other file, and .webp / .avif are not accepted
  • upload and get return fullSizeUrl, the public CDN URL to embed in campaign HTML; list adds totalFileSizeInBytes

mailchimp_search tool
  • scope (members or campaigns) and query; audienceId narrows a member search; includeTopN (1–100, default 10) caps each result array
  • Members return as exact and fuzzy with upstream totalExact / totalFuzzy; campaigns as matches with a snippet and totalMatches; an empty result carries a note

mailchimp_assets tool
  • list, info (by relPath; returns sha256 and any cached upload), sync (uploads uncached files ahead of a send; returns uploaded, cached, and skipped with reasons), and clear-cache
  • @assets/<path> references in content passed to mailchimp_send_campaign, mailchimp_replicate_campaign, or mailchimp_campaigns set-content upload to File Manager and are rewritten to CDN URLs. Uploads are cached by SHA-256 in <assetsDir>/.mailchimp-cache.json; oversize files and paths outside the directory are rejected before upload
  • Listed only when MAILCHIMP_ASSETS_DIR is set

mailchimp_local_templates tool
  • list, get (source plus parsed metadata), render-preview (name plus vars; returns HTML, sends nothing), and seed-from-mailchimp (writes Mailchimp template mailchimpTemplateId to disk as name)
  • Templates are .eta files with optional YAML frontmatter for subject, previewText, and vars; a declared var left unsupplied fails the render. Campaign tools render one via content.localTemplate + content.localTemplateVars, exclusive with html and templateId. Example templates
  • Listed only when MAILCHIMP_TEMPLATES_DIR is set

mailchimp_playbook tool
  • topic: send, post-send-review, deliverability, list-hygiene, onboarding, subscriber-triage, or design-campaign; audienceId for send / list-hygiene / design-campaign, campaignId for post-send-review, email for subscriber-triage
  • Returns markdown instructions tuned to live numbers, a liveState snapshot, and nextToolSuggestions with pre-filled inputs; makes no writes

mailchimp://account resource
  • No parameters; application/json with profile, plan, data center, total subscribers, and fetchedAt
  • Same data as mailchimp_account operation: info

mailchimp://audiences/{audienceId} resource
  • Name, contact, stats, campaign defaults, permission reminder, double opt-in status, and subscribe URL
  • audienceId comes from mailchimp_audiences operation: list

mailchimp://campaigns/{campaignId} resource
  • Status, settings, recipients, tracking, and report summary
  • campaignId comes from mailchimp_campaigns operation: list

mailchimp://campaigns/{campaignId}/report resource
  • Emails sent, bounces, opens, clicks, unsubscribes, abuse reports, and industry stats
  • Fails with a validation error until the campaign has been sent

newsletter_from_source prompt
  • Arguments: source (URL or free-form brief) required; audienceId and seasonalContext optional
  • Returns one user message that chains mailchimp_playbook (topic: design-campaign) into an HTML draft, then draft, test, and send via mailchimp_send_campaign

Features

Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.

Mailchimp-specific:

  • Marketing API v3 client that derives the API host and data center from the key's -<dc> suffix, with retries, a process-wide concurrency limit (MAILCHIMP_CONCURRENCY_LIMIT), and a cooldown after a 429
  • Send gates: campaigns default to draft, send / schedule need confirmSend: true plus a confirmation prompt, and new or resumed subscribed subscriptions need confirmation too; imports default to pending
  • No irreversible deletes: removing audiences, merge fields, or campaigns, and permanently deleting subscribers, stay in the Mailchimp UI; archive is the strongest subscriber removal
  • Local authoring: @assets/<path> files upload and rewrite at send time, and .eta templates render locally, which covers free plans where the Templates API is read-only
  • List operations page with count (max 1000) and offset

Agent-friendly output:

  • Explained empties: note / notes[] on empty activity feeds, audience overviews, and searches say whether data is missing or genuinely zero
  • Partial failure: mailchimp_import_subscribers and mailchimp_segments batch-update-members return per-row successes and errors instead of failing the batch
  • Discriminated outputs: operation, dimension, and mode say which fields are populated; isNew and cancelledByUser report what actually happened
  • Typed errors: every declared reason (campaign_not_sent, pre_send_checklist_failed, mailchimp_forbidden, …) carries a recovery hint for the caller's next move

Getting started

Add the following to your MCP client configuration file. See docs/api-key.md for how to generate a Mailchimp API key.

{
  "mcpServers": {
    "mailchimp-mcp-server": {
      "type": "stdio",
      "command": "bunx",
      "args": ["@cyanheads/mailchimp-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info",
        "MAILCHIMP_API_KEY": "your-key-with-dc-suffix-e.g.-us22"
      }
    }
  }
}

Or with npx (no Bun required):

{
  "mcpServers": {
    "mailchimp-mcp-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cyanheads/mailchimp-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info",
        "MAILCHIMP_API_KEY": "your-key-with-dc-suffix-e.g.-us22"
      }
    }
  }
}

Or with Docker:

{
  "mcpServers": {
    "mailchimp-mcp-server": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "MCP_TRANSPORT_TYPE=stdio",
        "-e", "MAILCHIMP_API_KEY=your-key-with-dc-suffix-e.g.-us22",
        "ghcr.io/cyanheads/mailchimp-mcp-server:latest"
      ]
    }
  }
}

For Streamable HTTP, set the transport and start the server:

MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 MAILCHIMP_API_KEY=... bun run start:http
# Server listens at http://localhost:3010/mcp
Prerequisites
  • Bun v1.4.0 or higher (or Node.js v24+).
  • A Mailchimp Marketing API key. Its -dc suffix (e.g. -us22) identifies your data center and is parsed at startup.
Installation
  1. Clone the repository:
git clone https://github.com/cyanheads/mailchimp-mcp-server.git
  1. Navigate into the directory:
cd mailchimp-mcp-server
  1. Install dependencies:
bun install
  1. Configure environment:
cp .env.example .env
# edit .env and set MAILCHIMP_API_KEY

Configuration

VariableDescriptionDefault
MAILCHIMP_API_KEYRequired. Marketing API key, including the -dc suffix (e.g. abc…-us22).none
MAILCHIMP_BASE_URLAPI base URL override, for mock servers or tests.https://{dc}.api.mailchimp.com/3.0
MAILCHIMP_TIMEOUT_MSPer-request timeout, in ms.60000
MAILCHIMP_MAX_RETRIESRetry attempts for transient upstream failures (0–10).3
MAILCHIMP_CONCURRENCY_LIMITMax in-flight upstream requests across the process (1–10).4
MAILCHIMP_ASSETS_DIRAbsolute path to a local assets directory. Enables mailchimp_assets and @assets/<path> uploads in campaign HTML.none
MAILCHIMP_TEMPLATES_DIRAbsolute path to a local templates directory. Enables mailchimp_local_templates and content.localTemplate on campaign tools.none
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTHTTP server port.3010
MCP_SESSION_MODESession mode; confirmations need stateful, and stateless refuses HTTP startup (stdio is unaffected).stateful
MCP_REQUEST_STATE_KEYOptional sealing key, at least 32 bytes. Confirmations are single-use and tied to one process, so a restart or another instance asks again.none
MCP_AUTH_MODEAuthentication: none, jwt, or oauth.none
MCP_LOG_LEVELLog level (debug, info, warning, error, etc.).info
LOGS_DIRDirectory for log files (Node.js only).<app-root>/logs
OTEL_ENABLEDEnable OpenTelemetry.false
OTEL_EXPORTER_OTLP_ENDPOINTBase URL for traces and metrics.none
OTEL_EXPORTER_OTLP_LOGS_ENDPOINTOTLP log endpoint; log export is off unless this is set.none
LOG_TOOL_FAILURE_PAYLOADSLog failed-call arguments and results, redacted by key name and capped at LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES (default 16384). Secrets inside free-form values remain visible.false

See .env.example for the full list of optional overrides.

Running the server

Local development
  • Watch mode (transport via MCP_TRANSPORT_TYPE):
    bun run dev                           # stdio (default)
    MCP_TRANSPORT_TYPE=http bun run dev   # http
  • Build and run:
    bun run rebuild
    bun run start:stdio
    # or
    bun run start:http
  • Run checks and tests:
    bun run devcheck   # Lint, format, typecheck, security
    bun run test       # Vitest test suite
    bun run lint:mcp   # Validate MCP definitions against spec
Docker
docker build -t mailchimp-mcp-server .
docker run --rm -e MAILCHIMP_API_KEY=your-key-us22 -p 3010:3010 mailchimp-mcp-server

The Dockerfile defaults to HTTP transport, stateful session mode, and logs to /var/log/mailchimp-mcp-server. OpenTelemetry peer dependencies are installed by default; build with --build-arg OTEL_ENABLED=false to omit them.

Project structure

DirectoryPurpose
src/index.tscreateApp() entry point: registers tools, resources, and the prompt, and initializes services.
src/configMAILCHIMP_* environment variable parsing and validation with Zod.
src/mcp-server/toolsTool definitions (*.tool.ts) plus shared helpers for template rendering, asset rewriting, and send confirmation.
src/mcp-server/resourcesResource definitions (*.resource.ts).
src/mcp-server/promptsPrompt definitions (*.prompt.ts).
src/services/mailchimpMailchimp API client: HTTP, request pacing, retries, response normalization.
src/services/assetsLocal assets: discovery, hashing, upload cache, @assets/ rewriting.
src/services/templatesLocal templates: Eta rendering, frontmatter parsing, seeding from Mailchimp.
templates/Example .eta templates; point MAILCHIMP_TEMPLATES_DIR here to try them.
docs/API key guide and the email design playbook.
tests/Vitest suites for config, services, tools, and the prompt.

Development guide

See CLAUDE.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for request-scoped logging
  • Register new tools and resources via the barrels in src/mcp-server/*/definitions/index.ts
  • Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields

Contributing

Issues are welcome. Run checks and tests before submitting:

bun run devcheck
bun run test

License

Apache-2.0 — see LICENSE for details.

Frequently asked questions

What is io.github.cyanheads/mailchimp-mcp-server?

Mailchimp via MCP: draft, test, and send campaigns; manage audiences and subscribers; pull reports.

How do I install io.github.cyanheads/mailchimp-mcp-server?

It runs on your machine. In Claude Code: claude mcp add mailchimp-mcp-server -e 'MAILCHIMP_API_KEY=<MAILCHIMP_API_KEY>' -e 'MAILCHIMP_BASE_URL=<MAILCHIMP_BASE_URL>' -e 'MAILCHIMP_TIMEOUT_MS=60000' -e 'MAILCHIMP_MAX_RETRIES=3' -e 'MAILCHIMP_CONCURRENCY_LIMIT=4' -e 'MAILCHIMP_ASSETS_DIR=<MAILCHIMP_ASSETS_DIR>' -e 'MAILCHIMP_TEMPLATES_DIR=<MAILCHIMP_TEMPLATES_DIR>' -e 'MCP_LOG_LEVEL=info' -- npx -y @cyanheads/mailchimp-mcp-server@0.6.0. For other clients, paste the JSON configuration from this page into their MCP settings.

Does io.github.cyanheads/mailchimp-mcp-server need an API key?

Yes. It expects MAILCHIMP_API_KEY, which you set in its configuration.

Is io.github.cyanheads/mailchimp-mcp-server open source?

Yes. Its code is on GitHub under the Apache-2.0 license.

Who maintains io.github.cyanheads/mailchimp-mcp-server?

It is published by cyanheads. AI.tn lists it but does not maintain or endorse it.

From the official MCP Registry. Listing is not an endorsement: review a server's code and permissions before giving it access to your data.