Guides
CI/CD integration
Run Conductor in GitHub Actions, Docker-based pipelines, and automated workflows. HTTP transport required — stdio doesn't work in CI.
Key differences in CI
GitHub Actions
Start Conductor in the background, wait for the health check, then call tools via HTTP.
name: AI-assisted review
on:
pull_request:
types: [opened, synchronize]
jobs:
conductor-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Conductor
run: npm install -g @useconductor/conductor
- name: Start Conductor (HTTP transport)
run: |
conductor mcp start --transport http --port 3000 &
sleep 2
curl -sf http://localhost:3000/health
env:
CONDUCTOR_AUTH_TOKEN: ${{ secrets.CONDUCTOR_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Run review
run: |
curl -s -X POST http://localhost:3000/tools/call \
-H "Authorization: Bearer ${{ secrets.CONDUCTOR_TOKEN }}" \
-H "Content-Type: application/json" \
-d '{
"name": "git.diff",
"arguments": { "staged": false }
}'Docker Compose pipeline
Run Conductor as a sidecar container. Use the depends_on health check condition to ensure Conductor is ready before your test runner starts.
# docker-compose.ci.yml
version: "3.9"
services:
conductor:
image: ghcr.io/useconductor/conductor:latest
ports: ["3000:3000"]
environment:
CONDUCTOR_TRANSPORT: http
CONDUCTOR_AUTH_TOKEN: ${CONDUCTOR_TOKEN}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 5s
retries: 10
test-runner:
image: node:20
depends_on:
conductor:
condition: service_healthy
environment:
CONDUCTOR_URL: http://conductor:3000
CONDUCTOR_TOKEN: ${CONDUCTOR_TOKEN}
command: npm testUsing the SDK in scripts
For complex automation, use the TypeScript SDK instead of raw curl. It handles connection management and gives you typed tool results.
import { ConductorClient } from "@useconductor/sdk";
const conductor = new ConductorClient({
transport: "http",
url: process.env.CONDUCTOR_URL ?? "http://localhost:3000",
token: process.env.CONDUCTOR_TOKEN,
});
await conductor.connect();
// Run tests
const testResult = await conductor.callTool("shell.exec", {
command: "npm",
args: ["test", "--ci"],
});
// Parse output
const passed = testResult.content[0].text.includes("passing");
if (passed) {
// Auto-commit if tests pass
await conductor.callTool("git.commit", {
message: "chore: auto-commit after CI pass",
all: true,
});
}
await conductor.disconnect();Disabling approval gates in CI
Approval gates block on an interactive terminal prompt. In CI, there is no terminal. Disable them per-plugin in your CI config, or use a separate config file for CI runs.
{
"server": {
"transport": "http",
"port": 3000
},
"approvalGates": {
"enabled": false
},
"plugins": {
"shell": {
"allowedCommands": ["npm", "node", "git", "pytest"]
}
}
}Point at the CI config: CONDUCTOR_CONFIG_DIR=~/.conductor conductor mcp start --config config.ci.json
Secrets in CI
# In your CI environment (GitHub Actions secrets, etc.)
CONDUCTOR_TOKEN=your-secure-token-here
CONDUCTOR_LOG_LEVEL=warn
# Plugin credentials
GITHUB_TOKEN=ghp_...
SLACK_BOT_TOKEN=xoxb-...Store all credentials as CI secrets (GitHub: Settings → Secrets and variables). Never hardcode tokens.