Deployment Guide

April 28, 2026 ยท View on GitHub

Docker Deployment

Docker is the recommended deployment method. The project includes a production-ready Docker Compose stack.

Quick Start

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

This starts three services:

ServiceImagePortsDescription
opensips-mcpBuilt from docker/Dockerfile8080MCP server (streamable-http)
opensipsopensips/opensips:3.65060/udp, 5060/tcp, 8888OpenSIPS SIP proxy
mysqlmysql:8.03306Database backend

Verifying the Stack

Check that all services are running:

docker compose -f docker/docker-compose.yml ps

Test MI connectivity:

curl -s http://localhost:8888/mi/which | head -20

Test the MCP server:

curl -s http://localhost:8080/ | head -5

Docker Build Details

The Dockerfile uses a multi-stage build:

  1. Builder stage: Installs the Python package and MySQL dependencies.
  2. Runtime stage: Copies only the installed packages for a smaller image.
# Build just the MCP server image
docker compose -f docker/docker-compose.yml build opensips-mcp

Docker Scenario Images

Seven pre-built Docker scenarios are available under docker/scenarios/:

ScenarioDirectoryDescription
Call Centerdocker/scenarios/call-center/Call center with agent queues
Class 4 SBCdocker/scenarios/class4-sbc/Transit SBC with DR
Load Balancerdocker/scenarios/load-balancer/SIP load balancer
Registrardocker/scenarios/registrar-class5/Class 5 registrar
Residential PBXdocker/scenarios/residential-pbx/Home/office PBX
SBC + RTPEnginedocker/scenarios/sbc-rtpengine/SBC with media relay
WebRTC Gatewaydocker/scenarios/webrtc-gateway/WebRTC to SIP bridge

Each scenario directory contains its own Docker Compose file and OpenSIPS configuration.

Docker Ecosystem Stacks

Additional Docker stacks under docker/ecosystem/:

  • full-stack/ -- Complete OpenSIPS + MCP + database setup
  • monitoring/ -- Prometheus + Grafana monitoring stack
  • testing/ -- Integration testing environment

Bare Metal Deployment

Prerequisites

  • Python 3.10 or later
  • A running OpenSIPS instance with MI HTTP enabled
  • A database (MySQL, PostgreSQL, or SQLite)

Installation

# Create a dedicated user
useradd -r -m opensips-mcp

# Install from source
su - opensips-mcp
git clone https://github.com/your-org/opensips-mcp-server.git
cd opensips-mcp-server
python -m venv .venv
source .venv/bin/activate

# For MySQL backend
pip install -e ".[mysql]"

# For PostgreSQL backend
pip install -e ".[postgres]"

Configuration

cp .env.example .env
# Edit .env with production values

Essential production settings:

OPENSIPS_MCP_MI_URL=http://opensips.internal:8888/mi
OPENSIPS_MCP_DB_URL=mysql+asyncmy://opensips:password@db.internal:3306/opensips
OPENSIPS_MCP_TRANSPORT=streamable-http
# Bind to loopback and terminate TLS + auth at a reverse proxy (see nginx
# config under docker/nginx/). If you must bind to a non-loopback address,
# OPENSIPS_MCP_API_KEY is MANDATORY โ€” the server refuses to start otherwise.
OPENSIPS_MCP_HOST=127.0.0.1
OPENSIPS_MCP_PORT=8080
# Default to the least-privileged role. Only switch to `admin` when every
# authenticated client is trusted to mutate state.
OPENSIPS_MCP_ROLE=readonly
# Generate with: python -c "import secrets; print(secrets.token_urlsafe(32))"
OPENSIPS_MCP_API_KEY=replace-me-with-a-long-random-string
OPENSIPS_MCP_LOG_LEVEL=WARNING

Security note. The server aborts startup when it is configured to listen on a non-loopback interface (--host 0.0.0.0 or a public IP) without an API key. Either keep the bind on 127.0.0.1 and front it with an authenticated reverse proxy, or set OPENSIPS_MCP_API_KEY to a long random value.

Running as a systemd Service

Create /etc/systemd/system/opensips-mcp.service:

[Unit]
Description=OpenSIPS MCP Server
After=network.target opensips.service mysql.service

[Service]
Type=simple
User=opensips-mcp
WorkingDirectory=/home/opensips-mcp/opensips-mcp-server
EnvironmentFile=/home/opensips-mcp/opensips-mcp-server/.env
ExecStart=/home/opensips-mcp/opensips-mcp-server/.venv/bin/opensips-mcp \
    --transport streamable-http --host 127.0.0.1 --port 8080
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Enable and start:

systemctl daemon-reload
systemctl enable opensips-mcp
systemctl start opensips-mcp

Connecting to OpenSIPS

MI HTTP Configuration

The MCP server connects to OpenSIPS through the Management Interface (MI) over HTTP. Ensure your OpenSIPS configuration includes the mi_http module:

loadmodule "httpd.so"
modparam("httpd", "port", 8888)

loadmodule "mi_http.so"

Network Considerations

  • The MI HTTP port (default 8888) should only be accessible from the MCP server.
  • If OpenSIPS and the MCP server run on different hosts, use a private network or SSH tunnel.
  • Never expose the MI HTTP port to the public internet.

Production Considerations

TLS Termination with nginx

For production deployments, place the MCP server behind nginx with TLS:

upstream opensips_mcp {
    server 127.0.0.1:8080;
}

server {
    listen 443 ssl http2;
    server_name mcp.example.com;

    ssl_certificate     /etc/letsencrypt/live/mcp.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mcp.example.com/privkey.pem;

    location / {
        proxy_pass http://opensips_mcp;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }
}

The proxy_read_timeout and proxy_send_timeout should be set high to support long-lived SSE connections.

Logging

Configure logging for production:

OPENSIPS_MCP_LOG_LEVEL=WARNING

Direct audit logs to a file:

# In a startup script or custom entry point
import logging
handler = logging.FileHandler("/var/log/opensips-mcp/audit.log")
logging.getLogger("opensips_mcp.audit").addHandler(handler)

Resource Limits

For high-throughput environments:

  • Increase file descriptor limits (ulimit -n 65535).
  • Use MySQL or PostgreSQL instead of SQLite for concurrent access.
  • Monitor memory usage -- the MCP server is lightweight but database query results can be large.

Backup

Back up the OpenSIPS database regularly. The MCP server does not maintain its own state beyond what is in the OpenSIPS database.

Monitoring

Use the health_check tool or the opensips://stats/all resource to integrate with your monitoring system. The Docker ecosystem includes a Prometheus + Grafana stack under docker/ecosystem/monitoring/.