Mautic MCP Connector
Provides tools for interacting with a Mautic instance's REST API, enabling management of contacts, segments, companies, emails, campaigns, forms, stages, points, notes, reports, statistics, and do-not-contact entries.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Mautic MCP Connectorfind contacts with @acme.com emails and add them to the Newsletter segment"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mautic-mcp (Mautic MCP connector)
Local MCP connector for Mautic, the GPLv3 marketing automation platform. It talks to a Mautic instance you already run, over stdio or stateless Streamable HTTP. It does not start Mautic for you.
The connector uses Mautic's documented REST API only. It contains no Mautic source code.
TypeScript 6 is intentional. typescript-eslint strict type-aware rules need the JavaScript compiler API, which TypeScript 7 does not ship.
Setup
npm install
npm run ci # typecheck, lint, test, build
npm start # stdio
npm run start:http # Streamable HTTP at http://127.0.0.1:3000/mcp and /healthCopy .env.example to .env and export the variables in your shell, or set them in the client config. MAUTIC_BASE_URL is required. Point it at your Mautic origin, for example https://mautic.example.com or http://127.0.0.1.
Enable the API in Mautic before you connect:
Open Settings > Configuration > API Settings.
Turn API enabled on.
For basic auth, turn Enable HTTP basic auth on.
For OAuth2, open Settings > API Credentials, create an OAuth 2 client, and copy the client id and secret.
Clear Mautic's cache after you change API settings.
Basic auth (authentication.rst:8, authentication.rst:37) sends Authorization: Basic. OAuth2 client credentials (authentication.rst:46, authentication.rst:195) POST to {MAUTIC_BASE_URL}/oauth/v2/token with grant_type=client_credentials, then send Authorization: Bearer. The connector caches the access token, refreshes it before expires_in, and retries the request once after a 401.
Claude Desktop or any stdio client:
{
"mcpServers": {
"mautic": {
"command": "node",
"args": ["/workspace/connectors/mautic/dist/index.js"],
"env": {
"MAUTIC_BASE_URL": "https://mautic.example.com",
"MAUTIC_USERNAME": "api-user",
"MAUTIC_PASSWORD": "...",
"MAUTIC_CONTACT": "you@example.com"
}
}
}
}OAuth2 instead of basic: set MAUTIC_CLIENT_ID and MAUTIC_CLIENT_SECRET. If both pairs are present, set MAUTIC_AUTH_MODE to basic or oauth2.
Docker binds 0.0.0.0 inside the container, so MCP_HTTP_AUTH_TOKEN is required (at least 16 characters):
docker build -t mautic-mcp .
docker run -p 127.0.0.1:3000:3000 \
-e MAUTIC_BASE_URL=http://host.docker.internal \
-e MAUTIC_USERNAME=api-user \
-e MAUTIC_PASSWORD=your-password \
-e MCP_HTTP_AUTH_TOKEN=at-least-16-chars \
mautic-mcpRegister every tool with registerConnectorTool. Calling server.registerTool anywhere else fails lint.
Related MCP server: mcp-mautic
Environment
Variable | Default | Role |
| none, required | Mautic origin and optional path. |
| inferred |
|
| unset | Mautic user for basic auth |
| unset | Basic auth password. At least 8 characters. Never printed |
| unset | OAuth2 client id |
| unset | OAuth2 client secret. At least 8 characters. Never printed |
|
| Contact inside the User-Agent. Must not contain a secret |
|
| Local sliding-window cap |
|
| TTL for successful reads. |
|
| Upstream timeout |
|
| Cap for list |
|
|
|
|
| HTTP listen port. |
|
| HTTP bind address |
| unset | Bearer token for |
Invalid values are reported by field name and issue code. The rejected value is not included in the error. Secrets never appear in logs, tool output, or error text, including upstream bodies that echo them.
Tools
Routes are taken from Mautic developer docs (devdocs.mautic.org source, commit bb8818f, 2026-10-12) under docs/rest_api/. Paths below are relative to {MAUTIC_BASE_URL}/api. List tools accept start (default 0) and limit (default 30, capped by MAUTIC_MAX_LIMIT) and return {total, start, limit, items, nextStart}. Mautic collections are normalized to arrays. Keyed objects such as {"total":"2","contacts":{"47":{...}}} (contacts.rst:296) and real arrays both become items. An empty collection may be an object, for example {"total":"0","contacts":{}}. total may be a string or a number. Activity tools return {total, page, limit, maxPages, events, filters, order, types} instead of that page shape, and they do not trim events to limit.
mautic_search_contacts search uses Mautic search commands (contacts.rst:243), for example email:*@example.com, tag:vip, and segment:alias.
Tool | Method and path | Source | Notes |
|
|
| Search commands at |
|
|
| |
|
|
| Field aliases plus |
|
|
| PATCH so a missing id fails ( |
|
|
| Body |
|
|
| Body |
|
|
| Collection key |
|
|
| |
|
|
| |
|
|
| |
|
|
| |
|
|
|
|
|
|
| |
|
|
| |
|
|
| |
|
|
| |
|
|
| |
|
|
| Returns |
|
|
| Optional |
|
|
| Optional |
|
|
| |
|
|
| |
|
|
| |
|
|
| |
|
|
| |
|
|
| |
|
|
| |
|
|
| |
|
|
| |
|
|
| Optional |
|
|
| New |
|
|
| New |
|
|
|
|
|
|
|
|
|
|
| |
|
|
| |
|
|
| |
|
|
|
|
|
|
| Returns |
|
|
| Channel |
|
|
| Cross-check |
|
|
|
|
|
|
| Same filters ( |
|
|
| Cross-check |
|
|
| Cross-check |
|
|
| Normalized to |
|
|
| Collection key |
|
|
|
|
|
|
|
|
|
|
| Cross-check |
Read tools use readOnlyHint: true. Write and send tools use readOnlyHint: false. Add, update, tag, stage, and DNC-add tools set idempotentHint: true. Create, send, point-adjust, and webhook-create tools set idempotentHint: false. Remove tools, DNC remove, and webhook delete set destructiveHint: true.
Confirm and dry-run
Every write and send tool's input includes confirm: z.literal(true).optional(). The only accepted value is the boolean true. confirm: false and confirm: "true" fail Zod and make no upstream call, including no OAuth token fetch.
When confirm is omitted, the tool does not call Mautic. It returns a preview:
{
"dryRun": true,
"method": "POST",
"path": "api/contacts/new",
"body": { "email": "ada@example.com" },
"summary": "Create a contact via POST /api/contacts/new."
}One shared WritePlan is built by a pure function, then either previewed or executed. method is POST, PATCH, or DELETE. DELETE sends no body.
DNC add, DNC remove, webhook create, and webhook delete use that same confirm gate. A dry-run does not call Mautic, so webhook trigger names are checked only when confirm is true, against GET /api/hooks/triggers. Unknown names are an input error and are not posted. Webhook GET, list, create, and delete responses drop the signing secret before the result is returned or cached.
Limits
In-memory TTL cache (
MAUTIC_CACHE_TTL_SEC, default 60 seconds) for reads. A cache hit does not spend the local rate limit. The cache is dropped when the process exits. Writes skip the cache and clear it after a successful call so later reads refetch.Local sliding window (
MAUTIC_PER_MINUTE, default 60 requests per 60 seconds) around Mautic API calls. OAuth token fetch is a separatePOSTto/oauth/v2/token(authentication.rst:195).When the local window is full, the tool returns
isErrorwith a[rate-limit]message and a retry hint. Cached results are still served.Upstream limits still apply. HTTP 429 is
[rate-limit]and honorsRetry-After. HTTP 400 is[input]. HTTP 401 is[auth]. HTTP 403 is[upstream]. HTTP 404 is[not-found]. Mautic bodies{"errors":[{"message","code","type","details"}]}(detailsmay be a field map or[], andtypemay be null),{"error":{"message","code"}}, and OAuth{"error","error_description"}(getting_started.rst:13) are mapped into those codes. Field details are appended only when the message does not already include them.List
limitis capped byMAUTIC_MAX_LIMIT(default 100, hard max 500).Response bodies larger than 1,000,000 characters are rejected.
Passwords, client secrets, access tokens, and the Basic auth header are redacted from tool results, error text, and logs, including URL-encoded forms.
HTTP security
HTTP mode binds 127.0.0.1 by default (MCP_HTTP_HOST). Loopback hosts are 127.0.0.1, ::1, and localhost. A non-loopback host refuses to start unless MCP_HTTP_AUTH_TOKEN is set (minimum 16 characters). When the token is set, every /mcp request must send Authorization: Bearer <token>. The compare is constant-time. A missing or wrong token returns 401. /health stays unauthenticated and returns ok.
The Docker image sets MCP_HTTP_HOST=0.0.0.0, so you must pass MCP_HTTP_AUTH_TOKEN. Publish the port on localhost only: -p 127.0.0.1:3000:3000.
Tested against
Local Mautic 7.2.1 on PHP 8.4, 2026-10-17. The API and HTTP basic auth were enabled. An OAuth2 client-credentials client with the Administrator role was used. The mailer was null://null with the sync messenger, so email sends are discarded by Mautic and were exercised only for that reason. scripts/live-smoke.mjs called the built stdio server against http://127.0.0.1:8080.
Live quirks
Empty collections can be objects, not arrays.
totalcan be a numeric string.Validation errors look like
{"errors":[{"code":400,"message":"...","details":{"field":["..."]}}]}.detailsmay be[]. HTTP 500 uses"type": null.Several write responses use integer
success: 1(segment, company, and campaign membership, stage add, point adjust, and segment email send). Contact email send uses booleantrue. The connector does not coerce these.POST /emails/{id}/sendreturns{success, sentCount, failedRecipients}(emails.rst:829). A repeat send returnssentCount: 0when every current member already has a stat row, andemail.sentCountstays put. A member who has not received that email is counted.Point subtract docs name the body fields
eventnameandactionname(contacts.rst:1056). Mautic 7.2.1 ignores those lowercase names and stores the default labels. The connector sendseventNameandactionNamefor both plus and minus (contacts.rst:1000).eventsOrderbyDirdocs sayascordesc(webhooks.rst:349). Mautic 7.2.1 accepts onlyASCorDESC. The connector uppercases the value.Mautic 7.2.1 stores unknown webhook trigger names. The connector rejects unknown names when
confirmis true and does not POST them.Webhook GET, create, and delete responses include a signing
secret(webhooks.rst:138,webhooks.rst:341). It is removed before the tool result and before the read cache.DNC add docs show a short object (
contacts.rst:801). Mautic 7.2.1 returns the full contact.mautic_check_contact_dncreadsGET /contacts/{id}and returns the entries. DNC writes clear the read cache. The check tool caches the full contact, the same payload asmautic_get_contact, then returns only the entries.Contact fields are under
fields.allorfields.core, not a top-levelfirstname. Tags are objects{id, tag}. Removing a tag sends the name with a minus prefix (contacts.rst:603).GET /contacts/activity?limit=2can return more events thanlimitwhile echoinglimit. The connector does not trimevents.There is no delete-contact or delete-company tool. A live smoke run can leave a throwaway contact, company, and note behind.
License
This connector's code is MIT. See LICENSE. Copyright 2026 Issah Abubakari.
It is a separate program that talks to Mautic (GPLv3) only over its documented REST API. No Mautic code is copied or linked.
"Mautic" is a trademark of its owner, used only to describe compatibility. No endorsement is implied. This project does not include a Mautic logo.
User-Agent is mautic-mcp/0.1.0 (<MAUTIC_CONTACT>). Point MAUTIC_CONTACT at a real address before production use. You are responsible for complying with the Mautic instance's own access policy.
License
MIT, see LICENSE. This is an independent, unofficial connector and is not endorsed by the Mautic project or its owners.
This server cannot be deployed
Maintenance
Related MCP Connectors
- QuallaaOAuthcom.quallaa
Talk to your public-facing AI from any MCP client — Claude, ChatGPT, Cursor, Cline, Windsurf.
Managed MCP gateway with OAuth, per-agent permissions, shared accounts and activity logs.
API-first CRM for LLMs - contacts, companies, deals and activities over a native MCP server.
Skills, agents and memory in the cloud, plus a gateway to your other MCP servers.
Related MCP Servers
- FlicenseCqualityFmaintenanceEnables comprehensive integration with Mautic marketing automation platform, providing contact management, campaign automation, email operations, form management, analytics, and content management through natural language commands.684 npm34-
- AlicenseNot gradedqualityFmaintenanceComprehensive MCP server for the Mautic marketing automation API, providing 203 tools for managing contacts, campaigns, emails, segments, and more.2ISC
- FlicenseNot gradedqualityDmaintenanceA lightweight MCP server that connects Claude AI to Mautic marketing automation, enabling contact management, email sending, campaign operations, and analytics via natural language.1-
- AlicenseAqualityAmaintenanceEnables agents and scripts to drive a social publishing account through remote or local MCP tools: drafting, scheduling, approving and publishing posts, running durable background jobs with file attachments, and reading or editing Brand Memory, assets, and standing agents. Hosts can connect over OAuth with no API key, or run the stdio variant with a key for local disk tools.651MIT