Deploy

📦v1.0.0📅2026-03-10🔄Updated 2026-04-28👤Admin Team
administrationdeploymentmcpnode-red

MCP — Deployment Guide

Message Control Platform — Contact Policy Enforcement Engine


Prerequisites

Before deploying MCP, ensure the following requirements are met:

RequirementDetails
DockerVersion 20.10 or later
Docker ComposeVersion 2.x or later
Docker NetworkAn external Docker network named contact-policy-node must be created prior to deployment
S3-Compatible StorageAn S3 or MinIO instance for hosting blacklist files

Create the Docker Network

docker network create contact-policy-node

Quick Start

1. Create a Project Directory

mkdir mcp && cd mcp
mkdir -p config/node_red_data

2. Create compose.yml

Use the following template as your base configuration:

services:
  contact-policy-0:
    image: ernestmr/message-control-platform:latest
    container_name: contact-policy-0
    ports:
      - "1880:1880"
    volumes:
      - ./config/node_red_data:/data
    networks:
      - contact-policy-node
    restart: unless-stopped
    tty: true
    stdin_open: true
    depends_on:
      redis:
        condition: service_healthy
    command: ["/usr/src/node-red/wait-for-redis.sh"]

  redis:
    image: redis:latest
    container_name: cp-redis
    command: ["redis-server", "--save", "60", "1", "--loglevel", "warning"]
    ports:
      - "6379:6379"
    volumes:
      - mcp_redis_data:/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 2s
      retries: 5
    networks:
      - contact-policy-node

networks:
  contact-policy-node:
    external: true

volumes:
  mcp_redis_data:

3. Start the Services

docker compose up -d

4. Verify the Deployment

curl http://localhost:1880/api/v1/health

Expected response: OK


Configuration

Node-RED Web UI

Once running, the Node-RED flow editor is available at:

http://<host>:1880/

All policy workflows are pre-configured in the platform image. Use the web UI to review, customize, or extend the policy flows.

Flow Data Persistence

The volume mount ./config/node_red_data:/data ensures all flow configurations, credentials, and runtime state persist across container restarts.

[!IMPORTANT] On first launch, Node-RED will initialize the /data directory with default flow configurations. All subsequent customizations are stored in this directory.


S3 / MinIO Setup for Blacklists

MCP loads blacklist entries from CSV files stored in an S3-compatible object storage.

Bucket Structure

contact-policy/           ← Bucket name
  └── black-list/         ← Prefix (folder)
       ├── blacklist.csv
       ├── corporate.csv
       └── ...            ← Additional CSV files

CSV Format

Each line contains a single phone number (destination address):

000000000001
998901234567
998970123654

Configure S3 Connection in Node-RED

  1. Open the Node-RED web UI at http://<host>:1880/
  2. Navigate to the BlackList tab
  3. Double-click the LoadList node
  4. Configure the S3 connection:
    • Bucket namecontact-policy
    • Region — your S3 region
    • Endpoint — your S3/MinIO endpoint URL
    • Access Key — your S3 access key
    • Secret Key — your S3 secret key
  5. Repeat the same S3 configuration for the ReadAll node
  6. Click Deploy to save changes

Blacklist Management

Auto-Renewal

MCP supports automatic blacklist refresh from S3 on a configurable schedule. The auto-renewal is configured in the BlackList tab using a cron scheduler node.

When triggered, MCP will:

  1. Fetch the latest CSV files from S3
  2. Parse all entries
  3. Atomically write them into Redis
  4. Clean up stale entries from the previous load

Manual Refresh

To manually reload the blacklist, use the manual inject button in the BlackList tab of the Node-RED UI.


Counter Reset Scheduler

Contact policy strategies CP1 use daily and weekly counters that need periodic reset.

Automated Reset via Cron Container

Deploy the counter reset scheduler alongside MCP:

services:
  cp-redis-cron:
    image: ernestmr/cp-redis-cron:latest
    container_name: cp-redis-cron
    environment:
      REDIS_HOST: cp-redis
      REDIS_PORT: "6379"
    networks:
      - contact-policy-node
    restart: unless-stopped

This container runs two cron jobs:

ScheduleAction
Every day at 00:00Resets daily counters (d → 0) for all tracked recipients
Every Monday at 00:00Resets weekly counters (w → 0) for all tracked recipients

Manual Reset

Counter resets can also be triggered manually via the MCP API:

# Reset daily counters
curl http://localhost:1880/api/v1/dcp

# Reset weekly counters
curl http://localhost:1880/api/v1/wcp

Scaling

MCP supports horizontal scaling. Add additional instances by defining more services in your compose.yml:

  contact-policy-1:
    image: ernestmr/message-control-platform:latest
    container_name: contact-policy-1
    ports:
      - "1881:1880"
    volumes:
      - ./config/node_red_data:/data
    networks:
      - contact-policy-node
    restart: unless-stopped
    tty: true
    stdin_open: true
    depends_on:
      redis:
        condition: service_healthy
    command: ["/usr/src/node-red/wait-for-redis.sh"]

[!TIP] All instances share the same flow definitions and Redis backend. Use an external load balancer (e.g., Nginx, HAProxy, Traefik) to distribute traffic across instances.


Full Compose Example (Multi-Instance + Cron + MinIO)

services:
  contact-policy-0:
    image: ernestmr/message-control-platform:latest
    container_name: contact-policy-0
    ports:
      - "1880:1880"
    volumes:
      - ./config/node_red_data:/data
    networks:
      - contact-policy-node
    restart: unless-stopped
    tty: true
    stdin_open: true
    depends_on:
      redis:
        condition: service_healthy
    command: ["/usr/src/node-red/wait-for-redis.sh"]

  contact-policy-1:
    image: ernestmr/message-control-platform:latest
    container_name: contact-policy-1
    ports:
      - "1881:1880"
    volumes:
      - ./config/node_red_data:/data
    networks:
      - contact-policy-node
    restart: unless-stopped
    tty: true
    stdin_open: true
    depends_on:
      redis:
        condition: service_healthy
    command: ["/usr/src/node-red/wait-for-redis.sh"]

  redis:
    image: redis:latest
    container_name: cp-redis
    command: ["redis-server", "--save", "60", "1", "--loglevel", "warning"]
    ports:
      - "6379:6379"
    volumes:
      - mcp_redis_data:/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 2s
      retries: 5
    networks:
      - contact-policy-node

  cp-redis-cron:
    image: ernestmr/cp-redis-cron:latest
    container_name: cp-redis-cron
    environment:
      REDIS_HOST: cp-redis
      REDIS_PORT: "6379"
    networks:
      - contact-policy-node
    restart: unless-stopped

  minio:
    image: minio/minio:latest
    container_name: mcp-minio
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - mcp_minio_data:/data
    networks:
      - contact-policy-node
    command: server /data --console-address ":9001"

networks:
  contact-policy-node:
    external: true

volumes:
  mcp_redis_data:
  mcp_minio_data:

API Verification

After deployment, verify that the system is operational:

Health Check

curl http://localhost:1880/api/v1/health
# Expected: OK

Policy Check (Example)

curl -X POST http://localhost:1880/api/v1/check \
  -H "Content-Type: application/json" \
  -H "x-api-auth: <your_api_key>" \
  -d '{
    "task_id": "1",
    "transaction_id": "test-001",
    "app_id": 1,
    "esme": 100,
    "saddr": "COMPANY",
    "daddr": "998901234567",
    "message": "Hello",
    "strategy": "cp1"
  }'

Expected response (allowed):

{
  "state": "ok",
  "pass": true
}

Ports Reference

ServiceDefault PortDescription
Node-RED (instance 0)1880Flow editor + Policy API
Node-RED (instance N)1880 + NAdditional instances
Redis6379State storage
MinIO API9000S3-compatible API
MinIO Console9001MinIO web management UI