Production Deployment
dev vs run
dev | run | |
|---|---|---|
| Hot reload | Enabled (file watch) | Disabled |
| Intended for | Local development | Production |
# Development (Python)pmcp dev tools.py
# Development (TypeScript)pmcp dev tools.ts
# Production (Python)pmcp run tools.py
# Production (TypeScript)pmcp run tools.tsIn 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:
| Transport | Flag | When to use |
|---|---|---|
| stdio | --transport stdio | MCP client spawns protomcp as a subprocess (most common) |
| Streamable HTTP | --transport http | Remote or web-based MCP clients |
For Claude Desktop (local), stdio is the correct choice. For a remote server, use http.
# 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 8080Call timeout
The default call timeout is 5 minutes. Adjust for your workload:
# Long-running taskspmcp run tools.py --call-timeout 30mpmcp run tools.ts --call-timeout 30m
# Fast tools onlypmcp run tools.py --call-timeout 30spmcp run tools.ts --call-timeout 30sLogging
pmcp run tools.py --log-level debug # debug, info, warn, errorpmcp run tools.ts --log-level debugLogs are written to stderr in structured format.
systemd
Create /etc/systemd/system/protomcp.service:
[Unit]Description=protomcp MCP serverAfter=network.target
[Service]Type=simpleExecStart=/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 8080WorkingDirectory=/opt/mytoolsUser=protomcpRestart=on-failureRestartSec=5StandardOutput=journalStandardError=journal
[Install]WantedBy=multi-user.targetEnable and start:
sudo systemctl daemon-reloadsudo systemctl enable protomcpsudo systemctl start protomcpDocker
FROM python:3.12-slim
# Install protomcp binaryRUN 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 dependenciesWORKDIR /appCOPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txt
COPY tools.py .
EXPOSE 8080CMD ["pmcp", "run", "tools.py", "--transport", "http", "--host", "0.0.0.0", "--port", "8080"]requirements.txt:
protomcpBuild and run:
docker build -t mytools .docker run -p 8080:8080 mytoolsUnix socket path
By default, protomcp creates the unix socket at $XDG_RUNTIME_DIR/protomcp/<pid>.sock. Override with --socket:
pmcp run tools.py --socket /tmp/mytools.sockThis is useful when you have multiple tool processes and want predictable socket paths.
Multiple tool processes
Run separate protomcp instances for each tool file:
# Pythonpmcp run auth_tools.py --transport http --port 8081 &pmcp run data_tools.py --transport http --port 8082 &
# TypeScriptpmcp 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:
# systemdsystemctl status protomcp
# Dockerdocker inspect --format='{{.State.Health.Status}}' mytools-containerFor HTTP transports, a successful tools/list call indicates the server is healthy.