conductorv2

Deployment

Deployment guide

Run Conductor locally, in Docker, or as a remote shared server. Same binary, different transport.

Deployment options

Local (stdio)

Default. Your AI client spawns Conductor per-session. No setup beyond the config block. Best for solo developers.

Personal use, single machine

Local (HTTP)

Conductor runs as a background process on your machine. Useful when multiple clients need to share one instance.

Multiple local clients, webhooks

Remote server

Run Conductor on a VPS or in Docker. Team members connect from anywhere. Full webhook and SSE support.

Teams, CI/CD, shared infrastructure

Docker Compose

The fastest path to a production-ready remote deployment. Set CONDUCTOR_AUTH_TOKEN in your environment before starting.

docker-compose.yml
version: "3.9"
services:
  conductor:
    image: ghcr.io/useconductor/conductor:latest
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      CONDUCTOR_TRANSPORT: http
      CONDUCTOR_PORT: 3000
      CONDUCTOR_AUTH_TOKEN: ${CONDUCTOR_AUTH_TOKEN}
      CONDUCTOR_LOG_LEVEL: info
    volumes:
      # Persist config and audit logs
      - conductor_data:/home/conductor/.conductor
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 5s
      retries: 3

volumes:
  conductor_data:

Dockerfile (custom image)

Build your own image to bake in plugin configuration, custom plugins, or specific Node versions.

Dockerfile
FROM node:20-alpine

# Create non-root user
RUN addgroup -S conductor && adduser -S conductor -G conductor

WORKDIR /app
RUN npm install -g @useconductor/conductor

USER conductor

EXPOSE 3000
CMD ["conductor", "mcp", "start", "--transport", "http", "--port", "3000"]

systemd (Linux VPS)

Run Conductor as a system service with automatic restart, log journaling, and security hardening. Install Node.js 18+ and Conductor globally first.

/etc/systemd/system/conductor.service
[Unit]
Description=Conductor MCP Server
After=network.target

[Service]
Type=simple
User=conductor
WorkingDirectory=/home/conductor
ExecStart=/usr/bin/conductor mcp start --transport http --port 3000
Restart=on-failure
RestartSec=5
Environment=CONDUCTOR_AUTH_TOKEN=your-token-here
Environment=CONDUCTOR_LOG_LEVEL=info

# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/home/conductor/.conductor

[Install]
WantedBy=multi-user.target
terminal
# Install and enable
sudo systemctl daemon-reload
sudo systemctl enable conductor
sudo systemctl start conductor

# Check status
sudo systemctl status conductor

# View logs
journalctl -u conductor -f

Connecting AI clients to a remote server

Point your AI client at the remote Conductor instance instead of spawning a local process. Use the SSE transport URL.

claude_desktop_config.json
{
  "mcpServers": {
    "conductor": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/client-sse",
        "https://conductor.yourcompany.com"
      ],
      "env": {
        "CONDUCTOR_TOKEN": "your-bearer-token"
      }
    }
  }
}

Secrets and environment variables

Never put credentials in config.json. Pass them as environment variables. Conductor reads them at startup and stores encrypted copies in the OS keychain for future runs.

.env
# .env (never commit this)
CONDUCTOR_AUTH_TOKEN=your-secret-token
CONDUCTOR_LOG_LEVEL=info
CONDUCTOR_PORT=3000

# Plugin credentials
GITHUB_TOKEN=ghp_...
SLACK_BOT_TOKEN=xoxb-...
NOTION_API_KEY=secret_...

Production checklist

Enable bearer token auth

CONDUCTOR_AUTH_TOKEN or config.server.auth

Put it behind a reverse proxy

nginx or Caddy — TLS termination, rate limiting

Run as a non-root user

Dedicated conductor system user

Mount a persistent volume for ~/.conductor

Config, audit logs, and encrypted secrets survive restarts

Set CONDUCTOR_LOG_LEVEL=warn in production

info is noisy at scale

Ship audit logs to a SIEM

audit.log is newline-delimited JSON — easy to forward

Configure allowlists before enabling shell plugin

Default is no commands allowed

Test the health endpoint in your monitoring

GET /health returns 200 with version + uptime