famulus-worker
The machine-side half of Famulus. It runs
Claude Code sessions on your computer, where your repositories, your tooling and
your claude login already live, and reports progress back to the Famulus backend.
Connections are outbound only. The worker dials the backend over WebSocket, so your machine needs no open ports, no port forwarding and no public IP.
┌─────────────┐ outbound ws ┌──────────────┐
│ worker │ ───────────────► │ backend │ ◄──── browser
│ (your Mac) │ ◄─────────────── │ (anywhere) │
└─────┬───────┘ tasks, replies └──────────────┘
│
▼ tmux session per task
`claude` ── writes result JSON ── picked up by the worker
⚠️ Read this before installing
The worker starts claude with --permission-mode auto and pre-accepts the
workspace trust prompt, because a pipeline can't answer interactive dialogs. In
practice that means:
- Claude will read, write and delete files in the working directory you configure, and run shell commands there, without asking for confirmation.
- Task titles, descriptions and imported ticket text are fed into that session as instructions. Treat anything you import as untrusted input. A hostile ticket description is a prompt-injection vector that can reach your shell.
- The backend can ask the worker to open an interactive terminal on this machine, relayed to whoever is authenticated to the web UI.
Run it against directories you're willing to let an agent modify, with a backend only you can reach. See SECURITY.md for the full trust model.
Requirements
- Python 3.12+
tmuxonPATH- Claude Code (
claude) onPATH, already signed in - A reachable Famulus backend
Install
uv tool install famulus-worker
Other installation methods
pipx install famulus-worker # isolated, also fine
pip install famulus-worker # into the current environment
# from a checkout
git clone https://github.com/getfamulus/famulus-worker && cd famulus-worker
uv sync && uv run famulus-worker --help
Run
famulus-worker --api http://localhost:8000 --worker-token "$FAMULUS_WORKER_TOKEN"
The token has to match the backend's FAMULUS_WORKER_TOKEN, or FAMULUS_AUTH_TOKEN if
you didn't configure a separate worker credential. On success you'll see:
Worker starting (reverse tunnel mode)
API: http://localhost:8000
Claude: /opt/homebrew/bin/claude
Connected to backend relay
Options
| Flag | Env | Default | Description |
|---|---|---|---|
--api |
FAMULUS_API |
http://localhost:8000 |
Backend base URL |
--worker-token |
FAMULUS_WORKER_TOKEN |
none | Worker credential (preferred) |
--token |
FAMULUS_TOKEN |
none | Fallback credential if no worker token is set |
--poll-interval |
none | 3 |
Seconds between task polls |
Keeping it running
macOS launchd example
Save to ~/Library/LaunchAgents/dev.famulus.worker.plist, then
launchctl load ~/Library/LaunchAgents/dev.famulus.worker.plist.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>dev.famulus.worker</string>
<key>ProgramArguments</key>
<array>
<string>/Users/you/.local/bin/famulus-worker</string>
<string>--api</string><string>https://famulus.example.com</string>
</array>
<key>EnvironmentVariables</key>
<dict><key>FAMULUS_WORKER_TOKEN</key><string>replace-me</string></dict>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
</dict>
</plist>
How it works
- Poll. Ask the backend for steps whose status is
running, grouped by stage. - Session. Ensure a detached tmux session per task (
tr-<taskid>) running one persistentclaudeconversation keyed to the task id, so later stages keep context. - Dispatch. Paste a stage prompt into the session via a tmux paste-buffer, never a shell string, so task text can't escape into your shell. Claude is asked to fan out one subagent per parallel job.
- Collect. Claude writes
{"status","output"}JSON per job into<working_dir>/.tr/<task_id>/. The worker posts each result and deletes the file. - Relay. On request, open a PTY (attaching to the task's tmux session when there is one) and stream it to the browser through the backend.
State lives in ~/.famulus/: pane logs, session and dispatch markers, attachment cache.
Those markers are what make a restart adopt in-flight work instead of re-running it.
Worktrees (optional)
If a task asks for a git worktree, the worker runs
~/.claude/utils/worktree-new.sh <ticket-id> in the repository and expects it to print
WORKTREE_PATH=<path>. Supply your own script at that path. There's a reference
implementation in examples/worktree-new.sh.
Troubleshooting
| Symptom | Cause |
|---|---|
Backend closed during auth, reconnecting… |
Token mismatch. It must equal the backend's FAMULUS_WORKER_TOKEN |
claude cannot run: Login expired |
The CLI's login lapsed. Run claude on this machine, sign in, then re-run the task |
Session … did not report ready |
claude was slow or isn't signed in. Run claude once by hand |
| Steps stay "running" forever | No tmux, or Claude never wrote a result file. Open the live terminal to look |
Worktree failed |
Your worktree-new.sh is missing or didn't print WORKTREE_PATH= |
Development
uv sync
uv run famulus-worker --help
uv build
License
MIT, see LICENSE.
Metadata
Release files for famulus-worker 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| famulus_worker-0.1.2.tar.gz | 24.4 kB | With provenance | Details for famulus_worker-0.1.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| famulus_worker-0.1.2-py3-none-any.whl | Python 3 | none | any | Details for famulus_worker-0.1.2-py3-none-any.whl |
Total release size: 40.8 kB
Release files / famulus_worker-0.1.2.tar.gz
| Download URL | famulus_worker-0.1.2.tar.gz |
|---|---|
| Size | 24.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
52fe934643215e70c0f77c6f66d4e1c84dbc53ceaf0cdd13f9ffc297567411b2
|
|
BLAKE2b-256 checksum How to use checksums |
da589d7267ac9095568323079c3005eca887ffe4d2a302ea006014a61bc71a14
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 31, 2026.
Transparency logRelease files / famulus_worker-0.1.2-py3-none-any.whl
| Download URL | famulus_worker-0.1.2-py3-none-any.whl |
|---|---|
| Size | 16.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5f5064bb48a52f0b71a2b2825c6efc5ebd07a4ff144b337acf17ce6baeaf7ca6
|
|
BLAKE2b-256 checksum How to use checksums |
3bdbcc9973b61ecf603859ce1614acc219ebd17f98647e05de11f66dd12c5821
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 31, 2026.
Transparency logSecurity for famulus-worker 0.1.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for famulus_worker-0.1.2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 31, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.