Worker Setup
Run a TARS worker on your own infrastructure. Self-hosted workers give you full control over the execution environment, no data leaves your network, and you can scale compute independently.
tarsai.dev (Railway) through a Cloudflare Tunnel to the TARS Controller API on your Mac Mini (port 8421), then to the TARS daemon. Self-hosted workers integrate at the daemon level and poll tarsai.dev for tasks directly.
Prerequisites
- Linux or macOS (Ubuntu 22.04+ recommended for production)
- Python 3.10 or higher
- Git 2.35+
- Claude CLI installed and authenticated (
claude --versionshould work) - Outbound HTTPS access to
api.anthropic.comand your GitHub instance - A TARS worker API key (see below)
Step 1 — Obtain a Worker API Key
Register a new worker via the Worker Register API. This requires your account's TARS API key, which is set as the TARS_API_KEY environment variable on Railway and in tars.conf on your Mac Mini controller.
curl -s -X POST https://tarsai.dev/api/workers/register/ \
-H "Content-Type: application/json" \
-H "X-API-Key: <your-TARS_API_KEY>" \
-d '{
"hostname": "my-worker-01",
"capacity": 2
}'
Save the returned api_key — this is your worker API key (different from the account-level TARS_API_KEY) and you'll use it in the next step.
Step 2 — Install TARS Worker
Clone the TARS worker repository
git clone https://github.com/dsneed123/tars-worker.git
cd tars-worker
Create a Python virtual environment
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Configure the worker
Copy the example config and fill in your values:
cp tars.conf.example tars.conf
Edit tars.conf:
# Required
TARS_API_URL=https://tarsai.dev
TARS_WORKER_KEY=<your-api-key>
# Optional
TARS_WORKER_CAPACITY=2 # concurrent tasks
TARS_POLL_INTERVAL=15 # seconds between polling
TARS_REPOS_DIR=/var/tars/repos # scratch directory for clones
TARS_LOG_LEVEL=INFO
Start the worker
./tars.sh start
Verify it's running:
./tars.sh status
You should see output like:
TARS worker: running (PID 12345)
Last heartbeat: 2 seconds ago
Current load: 0 / 2
Step 3 — Running as a systemd Service
For production deployments, run TARS as a systemd service so it restarts automatically on reboot or failure.
# /etc/systemd/system/tars-worker.service
[Unit]
Description=TARS Worker
After=network.target
[Service]
Type=forking
User=tars
WorkingDirectory=/opt/tars-worker
PIDFile=/opt/tars-worker/state/tars.pid
ExecStart=/opt/tars-worker/tars.sh start
ExecStop=/opt/tars-worker/tars.sh stop
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable tars-worker
sudo systemctl start tars-worker
Step 4 — GitHub Access
The worker needs to clone and push to your repositories. Choose one of:
Option A — SSH deploy key (recommended)
# Generate a key pair (no passphrase)
ssh-keygen -t ed25519 -C "tars-worker" -f ~/.ssh/tars_deploy
# Add the public key as a deploy key in GitHub:
# Repository → Settings → Deploy keys → Add deploy key
# Check "Allow write access"
cat ~/.ssh/tars_deploy.pub
Tell TARS to use this key by adding to tars.conf:
GIT_SSH_KEY=/home/tars/.ssh/tars_deploy
Option B — GitHub personal access token
GITHUB_TOKEN=ghp_xxxxxxxxxxxx
tars.conf. Restrict file permissions: chmod 600 tars.conf and run the worker as a dedicated low-privilege user.
Monitoring Your Worker
View live worker status in the member dashboard under Workers (admin accounts). Workers that miss heartbeats for more than 5 minutes are marked offline automatically.
Useful commands
# View logs
./tars.sh logs
# Stop the worker gracefully
./tars.sh stop
# Run a single task poll cycle (for debugging)
./tars.sh run-once
Troubleshooting
Worker shows offline in the dashboard
Check that the worker process is running (./tars.sh status), that TARS_API_URL is correct, and that outbound HTTPS to that URL isn't blocked by a firewall.
Tasks fail immediately with "Clone failed"
Verify your SSH key or GitHub token has write access to the repository and that the repository URL in your project settings is correct.
Claude CLI not found
Ensure claude is on the worker's PATH and is authenticated. Run claude --version as the same user that runs the worker process.
Tunnel issues (Railway → Mac Mini)
The Cloudflare Tunnel URL is temporary by default and changes on restart. If task forwarding stops working:
- Restart the tunnel on your Mac Mini:
cloudflared tunnel --url http://localhost:8421 - Copy the new
*.trycloudflare.comURL from the output - Update
TARS_CONTROLLER_URLin your Railway environment variables to the new URL - Redeploy (or wait for the next request — Railway picks up env var changes immediately)
For a permanent URL, set up a named Cloudflare tunnel with a fixed subdomain instead of using the quick-tunnel command above.
Worker can't reach tarsai.dev
Confirm outbound HTTPS from your Mac Mini is not blocked. Test with: curl -I https://tarsai.dev. If you're behind a corporate firewall, port 443 must be open to Railway's IP ranges.
Next Steps
- API Reference — integrate task submission into your CI/CD pipeline
- FAQ — common questions about workers and task execution