Skip to content

Deployment guide

Single-server bare‑metal deployment: npm CLI (recommended for a production VM), from-source install, systemd, reverse proxy, and sizing.

Reading order

RequirementVersionNotes
Node.js24+LTS recommended
npm10+For npm i -g agent-detective
gitAny recentRequired for local-repos
OSUbuntu 22.04+ / Debian 12+ / macOS 13+Linux with systemd for the units below

Install your agent CLI (OpenCode, Claude, Cursor) on the same host and ensure it is on PATH for the service user.

RequirementVersionNotes
Node.js24+LTS recommended
pnpm10+As in packageManager in root package.json
gitAny recentFor cloning the repository
OSUbuntu 22.04+ / Debian 12+ / macOS 13+Any Unix with systemd (optional)
TierCPURAMDiskUse case
Minimal1 core1 GB10 GBDevelopment / testing
Recommended2 cores4 GB20 GBProduction workloads

configuration-hub.md documents merge order and top-level keys. Repository context (e.g. gitLogMaxCommits) belongs under local-repos-plugin options, not as a root repoContext key.

Run agent-detective init to scaffold config/local.json, or edit manually. Full plugin fields: generated/plugin-options.md.

Edit under /opt/agent-detective/config/ (local.json at minimum). See configuration.md.

Use a fixed install root (this guide uses /opt/agent-detective):

  • /opt/agent-detective/config/local.json (and optional overrides)
  • Global agent-detective on PATH (installed as the agent-detective user or system-wide)

Create a dedicated user and layout:

Layout and install
sudo useradd -r -s /usr/sbin/nologin -d /opt/agent-detective agent-detective
sudo mkdir -p /opt/agent-detective/config
sudo chown -R agent-detective:agent-detective /opt/agent-detective
# Install Node 24+ on the host, then as the service user:
sudo -u agent-detective bash -lc 'npm i -g agent-detective && cd /opt/agent-detective && agent-detective init'

Smoke-check before enabling systemd (doctor checks — config, agent, plugins, repos, port):

Validate install
sudo -u agent-detective agent-detective doctor --config-root /opt/agent-detective

Optional smoke with the server running in another session: agent-detective smoke --config-root /opt/agent-detective.

validate-config only checks JSON/Zod; doctor is the full preflight. See CLI reference.

Optional: load secrets from a root-owned env file (paths on the configuration.md env whitelist), for example:

/etc/systemd/system/agent-detective.service.d/override.conf
[Service]
EnvironmentFile=-/etc/agent-detective.env

Create /etc/systemd/system/agent-detective.service:

/etc/systemd/system/agent-detective.service
[Unit]
Description=Agent Detective
After=network.target
[Service]
Type=simple
User=agent-detective
Group=agent-detective
WorkingDirectory=/opt/agent-detective
ExecStart=/usr/bin/env agent-detective --config-root /opt/agent-detective
Restart=always
RestartSec=5
Environment=NODE_ENV=production
Environment=PORT=3001
[Install]
WantedBy=multi-user.target

The HTTP server listens on all interfaces (0.0.0.0) for the port you set (port in config or PORT). In production, use a host firewall so only nginx (same host) or your mesh can reach that port, while 443 is the public entry (see Security below).

Enable and start (npm CLI)
sudo systemctl daemon-reload
sudo systemctl enable agent-detective
sudo systemctl start agent-detective
sudo journalctl -u agent-detective -f

When the service is healthy on localhost, continue with Reverse proxy (nginx) below so public webhooks and HTTPS hit nginx, not the Node listener directly.

Put nginx (or your edge) in front of the app: forward to the process on 127.0.0.1:3001 (or your PORT / port). Terminate TLS at nginx. Ensure the app port is not exposed publicly except via the proxy (firewall PORT from the internet, allow 443).

Canonical HTTPS example in this repo (use this; do not maintain a second copy in other docs). Point proxy_pass at the port the app listens on (default 3001 unless overridden by PORT / config).

nginx reverse proxy
server {
listen 443 ssl;
server_name agent-detective.example.com;
ssl_certificate /etc/ssl/certs/example.com.pem;
ssl_certificate_key /etc/ssl/private/example.com.key;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:3001;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
proxy_buffering off;
chunked_transfer_encoding on;
}

Alternate path when you maintain a git clone on the server (fork, custom packages, or you prefer pnpm start).

Clone, install, and build
git clone https://github.com/andezdev/agent-detective.git
cd agent-detective
pnpm install
pnpm run build
pnpm run build:app

Use your own fork’s https://github.com/<owner>/<repo>.git URL if you are not building from the upstream repository.

Edit config/default.json (and optional config/local.json). See configuration.md.

Start the server
pnpm start

For development with hot reload: pnpm run dev. See development.md.

The unit file, EnvironmentFile, and systemctl commands are documented in npm CLI (end-to-end) above. TLS and nginx follow in Reverse proxy (nginx).

Create /etc/systemd/system/agent-detective.service:

/etc/systemd/system/agent-detective.service
[Unit]
Description=Agent Detective
After=network.target
[Service]
Type=simple
User=agent-detective
WorkingDirectory=/opt/agent-detective
ExecStart=/usr/bin/pnpm start
Restart=always
RestartSec=5
Environment=NODE_ENV=production
Environment=PORT=3001
[Install]
WantedBy=multi-user.target
Set up systemd service (from-source tree)
sudo useradd -r -s /usr/sbin/nologin agent-detective
sudo mkdir -p /opt/agent-detective
sudo cp -r . /opt/agent-detective
sudo chown -R agent-detective:agent-detective /opt/agent-detective
cd /opt/agent-detective
sudo -u agent-detective pnpm install
sudo -u agent-detective pnpm run build
sudo -u agent-detective pnpm run build:app
sudo systemctl daemon-reload
sudo systemctl enable agent-detective
sudo systemctl start agent-detective

View logs: sudo journalctl -u agent-detective -f.

  • Restrict firewall to SSH, HTTP, HTTPS as needed: sudo ufw allow 22/tcp && sudo ufw allow 80/tcp && sudo ufw allow 443/tcp && sudo ufw enable
  • Jira: configure webhook URL and, if used, shared secrets in Jira; prefer JIRA_API_TOKEN / JIRA_EMAIL / JIRA_BASE_URL from the environment (see configuration.md) instead of tokens in config files.

The HTTP API is under /api.

  • GET /api/health — JSON includes "status": ok | degraded | unhealthy (see observability.md).
  • GET /api/agent/list — agent availability
Health and agent checks
curl -sS http://localhost:3001/api/health
curl -sS http://localhost:3001/api/agent/list

Interactive docs UI: GET /docs (Scalar OpenAPI reference).

Structured logs go to stdout/stderr (captured by journald under systemd). Set log level via observability / LOG_LEVEL / OBSERVABILITY_LOG_LEVEL (see configuration.md).

SymptomWhat to check
Server won’t startValid JSON in config/*.json, port free: sudo lsof -i :3001
CLI not found in systemdwhich agent-detective as the service user; global npm bin on PATH
Plugin load failure (npm CLI)npm ls -g agent-detective; reinstall: npm i -g agent-detective@latest
Plugin load failure (from source)node_modules/@agent-detective/*/dist/, pnpm run build
Jira webhooksmockMode: false, env JIRA_*, webhook URL reachable from Atlassian
Agent unavailablewhich opencode (or your agent) in the same environment as the process; GET /api/agent/list
High memoryLower repoContext.gitLogMaxCommits in local-repos options