MCP server for Listmonk newsletter management (3rd-party fork). https://rhnvrm.github.io/listmonk-mcp/
  • Python 97.5%
  • Dockerfile 1.7%
  • Nix 0.8%
Find a file
Julian Lindner d39ff97adb
All checks were successful
CI / python (push) Successful in 16s
CI / docker (push) Successful in 10s
Merge pull request 'chore: release v0.2.1' (#12) from release/v0.2.1 into master
2026-09-08 23:10:06 +00:00
.forgejo/workflows feat(deploy): streamable-HTTP transport, image and CI 2026-08-25 12:24:44 +08:00
.github/workflows docs: update documentation and workflows 2025-08-06 19:59:11 +05:30
docs docs: update documentation and workflows 2025-08-06 19:59:11 +05:30
scripts test: update release tag fixture 2026-09-08 23:09:06 +00:00
src/listmonk_mcp chore: release v0.2.1 2026-09-08 23:05:42 +00:00
tests fix: classify Honoka Listmonk reads 2026-09-08 22:56:06 +00:00
.dockerignore feat(deploy): streamable-HTTP transport, image and CI 2026-08-25 12:24:44 +08:00
.env.example feat(deploy): streamable-HTTP transport, image and CI 2026-08-25 12:24:44 +08:00
.envrc Initial implementation: Listmonk MCP server foundation 2025-07-13 01:35:33 +05:30
.gitignore chore: include uv.lock file for reproducible builds 2025-08-06 14:16:34 +05:30
.python-version feat(deploy): streamable-HTTP transport, image and CI 2026-08-25 12:24:44 +08:00
AGENTS.md docs(agents): why master requires CI / python* and not CI / docker 2026-08-27 10:02:03 +08:00
CLAUDE.md feat(deploy): streamable-HTTP transport, image and CI 2026-08-25 12:24:44 +08:00
Dockerfile chore: release v0.2.1 2026-09-08 23:05:42 +00:00
flake.lock Initial implementation: Listmonk MCP server foundation 2025-07-13 01:35:33 +05:30
flake.nix Initial implementation: Listmonk MCP server foundation 2025-07-13 01:35:33 +05:30
HARDGATE_DESIGN.md feat(listmonk-mcp): add read-only preview tools and production-send hard-gate design 2026-09-08 12:05:10 +08:00
LICENSE chore: Create LICENSE 2025-07-13 03:20:03 +05:30
mkdocs.yml feat: add GitHub Actions workflow for MkDocs Material documentation 2025-08-06 13:41:05 +05:30
pyproject.toml chore: release v0.2.1 2026-09-08 23:05:42 +00:00
README.md chore: release v0.2.1 2026-09-08 23:05:42 +00:00
uv.lock chore: release v0.2.1 2026-09-08 23:05:42 +00:00

Listmonk MCP Server

An MCP (Model Context Protocol) server implementation for Listmonk, providing programmatic access to newsletter and mailing list management functionality.

Listmonk MCP Logo

Project Status

Implementation Complete - The core MCP server is fully implemented and functional.

Goal

Create an MCP server that enables LLMs and AI assistants to interact with Listmonk instances through the Model Context Protocol. This will allow for:

  • Subscriber management (add, remove, update subscribers)
  • Mailing list operations (create, manage lists)
  • Campaign management (create, send newsletters)
  • Analytics and reporting access
  • Template and content management

Architecture

This server will bridge the MCP protocol with Listmonk's REST API, providing a standardized interface for AI models to interact with Listmonk installations.

Features

  • Complete Listmonk API Coverage: All major Listmonk operations supported
  • 70 MCP Tools: Subscriber, list, campaign, template, media, bounce, import, settings, and maintenance management — full campaign lifecycle (test/send/pause/cancel/delete/archive/analytics), bounce handling, bulk operations, and admin endpoints
  • MCP Resources: Easy access to subscriber, list, campaign, and template data
  • Async Operations: Built with modern async/await patterns
  • Type Safety: Full Pydantic model validation
  • Environment Configuration: Easy setup with environment variables

Installation

Install and run directly from PyPI without managing dependencies:

# Run directly (installs if needed)
uvx listmonk-mcp --help

# Or install globally
uvx install listmonk-mcp
listmonk-mcp --help

Using pip

pip install listmonk-mcp

Development Installation

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

Transports

The server speaks two transports. stdio is the default and is how a local MCP client runs it.

# stdio (default)
listmonk-mcp

# streamable-HTTP
LISTMONK_MCP_TRANSPORT=streamable-http listmonk-mcp
# or
listmonk-mcp --transport streamable-http

Under streamable-http the server opens two listeners:

default carries env override
public 0.0.0.0:3000 /mcp, /health LISTMONK_MCP_BIND_ADDR
internal 127.0.0.1:9090 /metrics LISTMONK_MCP_METRICS_BIND_ADDR

The metrics listener resolves its address as: explicit env, then {POD_IP}:9090, then 127.0.0.1:9090. It never defaults to 0.0.0.0, because /metrics must not be reachable through the same Service that carries /mcp.

Container image

docker build \
  --build-arg BUILD_VERSION=0.2.1 \
  --build-arg BUILD_REVISION="$(git rev-parse HEAD)" \
  --build-arg BUILD_CREATED="$(git show -s --format=%cI HEAD)" \
  -t listmonk-mcp:dev .

docker run --rm -p 3000:3000 \
  -e LISTMONK_MCP_URL=http://listmonk:9000 \
  -e LISTMONK_MCP_USERNAME=api-user \
  -e LISTMONK_MCP_PASSWORD=... \
  listmonk-mcp:dev

The image defaults LISTMONK_MCP_TRANSPORT to streamable-http and runs as UID 65532. Port 9090 is deliberately not EXPOSEd.

Development

Code Quality Checks

Run the same checks that are executed in the CI/CD pipeline:

# Install development dependencies
uv sync --extra dev

# Run linting (same as CI)
uv run ruff check src/ tests/ scripts/

# Auto-fix linting issues
uv run ruff check src/ tests/ scripts/ --fix

# Run type checking (same as CI)
uv run mypy src/ scripts/

# Run the test suite (same as CI)
uv run pytest

# Run all checks together
uv run ruff check src/ tests/ scripts/ \
  && uv run mypy src/ scripts/ \
  && uv run pytest \
  && uv run python scripts/check_buildcache_guard.py

Building and Testing

# Build the package (same as CI)
uv build

# Test CLI locally (using entry point)
uv run listmonk-mcp --help
uv run listmonk-mcp --version

# Or install locally and test
uv pip install -e .
listmonk-mcp --help

Version Management

To release a new version:

# 1. Update version in pyproject.toml (e.g., 0.0.1 -> 0.0.2)
# 2. Commit and tag
git add pyproject.toml
git commit -m "chore: bump version to 0.0.2"
git tag v0.0.2
git push origin master
git push origin v0.0.2

# GitHub Actions will automatically:
# - Run linting and type checking
# - Build and publish to PyPI  
# - Create GitHub release with auto-generated notes

Quick Start

1. Set up Listmonk (Local Development)

For testing, you can run a local Listmonk instance using Docker:

# Option 1: Use the provided compose file
docker compose -f docs/listmonk-docker-compose.yml up -d

# Option 2: Download the latest compose file
curl -LO https://github.com/knadh/listmonk/raw/master/docker-compose.yml
docker compose up -d

# Access Listmonk at http://localhost:9000
# Default credentials: admin / listmonk

2. Create API User and Token

  1. Access the Listmonk admin interface at http://localhost:9000/admin
  2. Login with the default credentials: admin / listmonk
  3. Navigate to Admin → Users (http://localhost:9000/admin/users)
  4. Create a new API user:
    • Click "Add new"
    • Enter a username (e.g., api-user)
    • Assign appropriate role/permissions
    • Save the user
  5. Generate an API token:
    • Click on the created user
    • Click "Generate API token"
    • Copy the generated token

3. Configure Environment Variables

The MCP server requires the following environment variables:

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

Important: The password field should contain the API token (not the user's login password). The server uses Listmonk's token authentication format: Authorization: token username:api_token.

Troubleshooting Configuration:

  • Verify variables: echo $LISTMONK_MCP_URL should show your Listmonk URL
  • Test API access: curl -H "Authorization: token username:api_token" http://localhost:9000/api/health
  • Common errors: "invalid session" or 403 errors indicate incorrect credentials

4. Run the MCP Server

# Using uv (recommended)
uv run python -m listmonk_mcp.server

# Or using the entry point
listmonk-mcp

Common Issues:

  • Connection refused: Listmonk server not running or wrong URL
  • Module not found: Install dependencies with uv install or pip install -e .