Skip to main content

Production-ready MCP server for Listmonk newsletter and mailing list management

Project description

Listmonk MCP Bridge

A production-ready Model Context Protocol (MCP) server for Listmonk, built to give AI assistants and automation agents structured access to newsletter, subscriber, mailing list, campaign, template, and reporting workflows.

Origin and fork notice

This repository began as an initial fork of rhnvrm/listmonk-mcp.

It has since evolved into listmonk-mcp-bridge: a production-ready MCP server for Listmonk with updated packaging, CLI entry points, environment-based configuration, validation, development tooling, and operational documentation suitable for real deployments.

Overview

listmonk-mcp-bridge bridges MCP clients with the Listmonk REST API. It enables LLMs, AI assistants, and automation workflows to interact with Listmonk through a typed and predictable interface instead of ad-hoc HTTP calls.

Typical use cases include:

  • Subscriber lookup, creation, updates, and lifecycle management
  • Mailing list discovery and management
  • Campaign creation, updates, and delivery workflows
  • Template and content operations
  • Analytics and reporting access
  • Agent-driven newsletter and communications automation

What changed for production readiness

Compared with the initial fork baseline, this package has been substantially updated, packaged, and hardened for production use under the listmonk-mcp-bridge package name.

Production-focused improvements include:

  • PyPI-ready packaging with uv, uvx, pip, and console entry points
  • Environment-based configuration suitable for local, staging, and production deployments
  • Async HTTP operations for reliable Listmonk API communication
  • Pydantic-based validation for safer input and output handling
  • CLI entry points via both listmonk-mcp-bridge and listmonk-mcp
  • Development tooling with Ruff, mypy, pytest, and build validation
  • Release workflow support for publishing to PyPI and GitHub releases
  • Clear operational notes for credentials, API tokens, and production safety

Features

  • Broad Listmonk API coverage for subscriber, list, campaign, and template workflows
  • 81 MCP tools covering all 72 Listmonk Swagger operations plus focused convenience workflows
  • MCP resources for structured access to Listmonk data
  • Async-first implementation built on modern Python patterns
  • Type-safe models using Pydantic validation
  • Environment-driven configuration for local, staging, and production environments
  • Developer tooling with Ruff, mypy, pytest, Black, and build checks

Tool behavior notes

  • update_subscriber uses Listmonk's PATCH /api/subscribers/{id} endpoint for partial updates. Omitted fields are not sent to Listmonk, so changing only name, status, lists, or attributes does not require an email.
  • create_template supports campaign, campaign_visual, and transactional (tx) templates, including subject and body_source.
  • create_campaign converts content_type="plain" bodies into escaped HTML paragraphs by default with auto_convert_plain_to_html=True. Set auto_convert_plain_to_html=False to send plain text unchanged. HTML bodies are always left unchanged.
  • Swagger-aligned tools cover public lists, subscriber opt-in/export/bounces/list membership, bounces, import status/logs/stop, campaign delete/status/stats/analytics/archive/test/content conversion, template preview/default, media lookup, and extended transactional messages.

Requirements

  • Python 3.11 or newer
  • A running Listmonk instance
  • A Listmonk API user and API token
  • One of the following package runners or installers:
    • uv / uvx recommended
    • pip

Installation

Run with uvx recommended

Run the server directly from PyPI without manually managing a virtual environment:

uvx listmonk-mcp-bridge --help

Install it as a globally available tool:

uvx install listmonk-mcp-bridge
listmonk-mcp-bridge --help

Install with pip

pip install listmonk-mcp-bridge

After installation, the following commands are available:

listmonk-mcp-bridge --help
listmonk-mcp --help

Configuration

The server is configured through environment variables.

Variable Required Description Example
LISTMONK_MCP_URL Yes Base URL of your Listmonk instance https://listmonk.example.com
LISTMONK_MCP_USERNAME Yes Listmonk API username api-user
LISTMONK_MCP_PASSWORD Yes Listmonk API token, not the account login password your-api-token

Example local configuration:

export LISTMONK_MCP_URL=http://localhost:9000
export LISTMONK_MCP_USERNAME=api-user
export LISTMONK_MCP_PASSWORD=your-generated-api-token

Listmonk token authentication uses the following format internally:

Authorization: token username:api_token

Quick start

1. Start Listmonk locally

For local development and testing, you can run Listmonk with Docker.

Using the compose file included in this repository:

docker compose -f docs/listmonk-docker-compose.yml up -d

Or using the official Listmonk compose file:

curl -LO https://github.com/knadh/listmonk/raw/master/docker-compose.yml
docker compose up -d

Listmonk should be available at:

http://localhost:9000

Default local credentials are typically:

admin / listmonk

2. Create a dedicated Listmonk API user

  1. Open the Listmonk admin interface.
  2. Navigate to Admin → Users.
  3. Create a dedicated API user, for example api-user.
  4. Assign only the permissions required by your MCP workflows.
  5. Generate an API token for that user.
  6. Use that token as LISTMONK_MCP_PASSWORD.

For production deployments, avoid using the default admin account. Create a dedicated API user with the minimum permissions required.

3. Export environment variables

export LISTMONK_MCP_URL=http://localhost:9000
export LISTMONK_MCP_USERNAME=api-user
export LISTMONK_MCP_PASSWORD=your-generated-api-token

4. Run the MCP server

With the installed console command:

listmonk-mcp-bridge

Or through uv during development:

uv run listmonk-mcp-bridge

You can also run the Python module directly:

uv run python -m listmonk_mcp.server

MCP client configuration

Most MCP clients can start this server as a local command. A typical configuration looks like this:

{
  "mcpServers": {
    "listmonk-mcp-bridge": {
      "command": "uvx",
      "args": ["listmonk-mcp-bridge"],
      "env": {
        "LISTMONK_MCP_URL": "https://listmonk.example.com",
        "LISTMONK_MCP_USERNAME": "api-user",
        "LISTMONK_MCP_PASSWORD": "your-api-token"
      }
    }
  }
}

If you installed the package globally, you can also use:

{
  "mcpServers": {
    "listmonk-mcp-bridge": {
      "command": "listmonk-mcp-bridge",
      "env": {
        "LISTMONK_MCP_URL": "https://listmonk.example.com",
        "LISTMONK_MCP_USERNAME": "api-user",
        "LISTMONK_MCP_PASSWORD": "your-api-token"
      }
    }
  }
}

Production notes

Before using this server in production, review the following recommendations:

  • Use HTTPS for your Listmonk instance.
  • Use a dedicated API user instead of an admin user.
  • Apply least-privilege permissions wherever possible.
  • Store credentials in your deployment secret manager, not in source control.
  • Rotate API tokens periodically.
  • Test campaign-related workflows against a staging Listmonk instance first.
  • Monitor Listmonk API logs for unexpected agent behavior.
  • Review any AI-generated campaign or subscriber changes before enabling fully automated flows.
  • Confirmed destructive operations emit structured audit logs on the listmonk_mcp.audit logger.
  • Query-driven bulk operations are rate limited per server process with LISTMONK_MCP_BULK_QUERY_RATE_LIMIT_PER_MINUTE (default 30; set 0 to disable).

Staging smoke tests

Smoke tests that touch a real Listmonk instance are skipped by default. To run them against staging, set:

export LISTMONK_MCP_RUN_STAGING_SMOKE=true
export LISTMONK_MCP_URL=https://listmonk-staging.example.com
export LISTMONK_MCP_USERNAME=your-api-user
export LISTMONK_MCP_PASSWORD=your-api-token
export LISTMONK_MCP_SMOKE_LIST_ID=1
export LISTMONK_MCP_SMOKE_CAMPAIGN_ID=1
export LISTMONK_MCP_SMOKE_EMAIL=qa@example.com
uv run pytest tests/test_staging_smoke.py -q

Troubleshooting

Verify environment variables

echo "$LISTMONK_MCP_URL"
echo "$LISTMONK_MCP_USERNAME"

Avoid printing API tokens in shared terminals, CI logs, or screenshots.

Test Listmonk API access

curl \
  -H "Authorization: token ${LISTMONK_MCP_USERNAME}:${LISTMONK_MCP_PASSWORD}" \
  "${LISTMONK_MCP_URL}/api/health"

Common issues

Problem Likely cause Fix
Connection refused Listmonk is not running or the URL is wrong Check LISTMONK_MCP_URL and Listmonk availability
403 or invalid session Invalid username/token or insufficient permissions Regenerate the API token and verify the API user permissions
Module not found Development dependencies are not installed Run uv sync --extra dev
CLI command not found Package not installed in the active environment Use uvx listmonk-mcp-bridge or reinstall the package

Development

Clone the repository and install development dependencies:

git clone https://github.com/mnbro/listmonk-mcp-bridge.git
cd listmonk-mcp-bridge
uv sync --extra dev

Run the development server:

uv run listmonk-mcp-bridge --help
uv run listmonk-mcp-bridge --version

Code quality

Run linting:

uv run ruff check src/

Automatically fix lint issues where possible:

uv run ruff check src/ --fix

Run type checking:

uv run mypy src/

Run tests:

uv run pytest

Run the main quality checks together:

uv run ruff check src/ && uv run mypy src/ && uv run pytest

Build locally

uv build

Validate the built distribution before publishing:

uvx twine check dist/*

Release process

To release a new version:

# 1. Update the version in pyproject.toml
# Example: 0.2.0 -> 0.2.1

# 2. Commit the version bump
git add pyproject.toml
git commit -m "chore: bump version to 0.2.1"

# 3. Tag the release
git tag v0.2.1

# 4. Push the branch and tag
git push origin master
git push origin v0.2.1

If GitHub Actions is configured, the release pipeline can run checks, build the package, publish to PyPI, and create a GitHub release.

Security

This package can perform real operations against your Listmonk instance, including subscriber and campaign changes. Treat access to the MCP server as privileged access.

Recommended safeguards:

  • Run the server only in trusted environments.
  • Keep API credentials out of repository files and logs.
  • Limit token permissions according to the workflows you actually need.
  • Prefer staging environments when testing new automations or agent behavior.
  • Review generated campaign content before sending to real audiences.

Attribution

This project was initially forked from rhnvrm/listmonk-mcp. The current listmonk-mcp-bridge package has been modified and extended for production-oriented packaging, configuration, validation, and operational use.

Listmonk is an independent open-source project. This package is not officially affiliated with or endorsed by the Listmonk maintainers.

License

This project is licensed under the MIT License. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

listmonk_mcp_bridge-0.1.6.tar.gz (101.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

listmonk_mcp_bridge-0.1.6-py3-none-any.whl (38.0 kB view details)

Uploaded Python 3

File details

Details for the file listmonk_mcp_bridge-0.1.6.tar.gz.

File metadata

  • Download URL: listmonk_mcp_bridge-0.1.6.tar.gz
  • Upload date:
  • Size: 101.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for listmonk_mcp_bridge-0.1.6.tar.gz
Algorithm Hash digest
SHA256 6561a8ebd3eb197404722f550afef91551ca9e8fab7443a57109318b6696347a
MD5 8832e9c84690bbf7940d0c58288237d5
BLAKE2b-256 faba911cebfd7801fa4b82431019c1da0a70287a6a62905f1d6de6792846f357

See more details on using hashes here.

File details

Details for the file listmonk_mcp_bridge-0.1.6-py3-none-any.whl.

File metadata

File hashes

Hashes for listmonk_mcp_bridge-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 0d45cc83c5d5160484f5c5e9af21b634dd288f2adb3dca88853a58b16a49ddc0
MD5 deef3b95e312494719ec392183f9552c
BLAKE2b-256 0695975076849965d173ed2989fe109363c21bf2aeb068b27ee15cc49c85341b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page