Skip to content

Production Deployment

dev vs run

devrun
Hot reloadEnabled (file watch)Disabled
Intended forLocal developmentProduction
Terminal window
# Development (Python)
pmcp dev tools.py
# Development (TypeScript)
pmcp dev tools.ts
# Production (Python)
pmcp run tools.py
# Production (TypeScript)
pmcp run tools.ts

In run mode, protomcp starts the tool process and does not watch for file changes. Reload requires restarting the protomcp process.


Choosing a transport

For production, choose the transport that matches your deployment topology:

TransportFlagWhen to use
stdio--transport stdioMCP client spawns protomcp as a subprocess (most common)
Streamable HTTP--transport httpRemote or web-based MCP clients

For Claude Desktop (local), stdio is the correct choice. For a remote server, use http.

Terminal window
# Remote HTTP server (Python)
pmcp run tools.py --transport http --host 0.0.0.0 --port 8080
# Remote HTTP server (TypeScript)
pmcp run tools.ts --transport http --host 0.0.0.0 --port 8080

Call timeout

The default call timeout is 5 minutes. Adjust for your workload:

Terminal window
# Long-running tasks
pmcp run tools.py --call-timeout 30m
pmcp run tools.ts --call-timeout 30m
# Fast tools only
pmcp run tools.py --call-timeout 30s
pmcp run tools.ts --call-timeout 30s

Logging

Terminal window
pmcp run tools.py --log-level debug # debug, info, warn, error
pmcp run tools.ts --log-level debug

Logs are written to stderr in structured format.


systemd

Create /etc/systemd/system/protomcp.service:

[Unit]
Description=protomcp MCP server
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/pmcp run /opt/mytools/tools.py --transport http --host 127.0.0.1 --port 8080
# For TypeScript: ExecStart=/usr/local/bin/pmcp run /opt/mytools/tools.ts --transport http --host 127.0.0.1 --port 8080
WorkingDirectory=/opt/mytools
User=protomcp
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target

Enable and start:

Terminal window
sudo systemctl daemon-reload
sudo systemctl enable protomcp
sudo systemctl start protomcp

Docker

FROM python:3.12-slim
# Install protomcp binary
RUN curl -L https://github.com/msilverblatt/protomcp/releases/latest/download/protomcp_linux_amd64.tar.gz \
| tar xz -C /usr/local/bin/
# Install Python SDK and tool dependencies
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY tools.py .
EXPOSE 8080
CMD ["pmcp", "run", "tools.py", "--transport", "http", "--host", "0.0.0.0", "--port", "8080"]

requirements.txt:

protomcp

Build and run:

Terminal window
docker build -t mytools .
docker run -p 8080:8080 mytools

Unix socket path

By default, protomcp creates the unix socket at $XDG_RUNTIME_DIR/protomcp/<pid>.sock. Override with --socket:

Terminal window
pmcp run tools.py --socket /tmp/mytools.sock

This is useful when you have multiple tool processes and want predictable socket paths.


Multiple tool processes

Run separate protomcp instances for each tool file:

Terminal window
# Python
pmcp run auth_tools.py --transport http --port 8081 &
pmcp run data_tools.py --transport http --port 8082 &
# TypeScript
pmcp run auth_tools.ts --transport http --port 8081 &
pmcp run data_tools.ts --transport http --port 8082 &

Configure each as a separate MCP server in your client.


Health monitoring

protomcp does not expose a health endpoint, but you can monitor the process directly:

Terminal window
# systemd
systemctl status protomcp
# Docker
docker inspect --format='{{.State.Health.Status}}' mytools-container

For HTTP transports, a successful tools/list call indicates the server is healthy.