Automated Claude Code execution in isolated environments
Project description
Iterare
Automated Claude Code execution in isolated Docker containers.
iterare creates git worktrees, launches containerised Claude Code instances with autonomous permissions, and
maintains safety through network firewalls and container isolation. This enables "agentic loops" where Claude
Code can modify codebases without human confirmation while being restricted to whitelisted network access and
mounted files.
Warning – This does not fully protect from malicious code execution or data exfiltration. It simply raises the barriers to these things happening. Use at your own risk.
Prerequisites
- Python 3.13+
- uv for dependency management
- Docker
- A Claude Code API key
Installation
# Install via pypi
pip install iterare-llm
# Create global config directories
iterare install
# Fetch Claude Code credentials (interactive Docker session)
iterare credentials
Quick Start
The easiest way to get started is to use the interactive mode. This launches a Claude Code session in a Docker container, mounts your current project directory, and allows you to drive Claude Code yourself.
# Initialize a project
cd /path/to/your/project
iterare init
# Launch in interactive mode
iterare interactive
Alternatively, you can create a prompt file and execute it. This (by default) creates a git worktree, and branches off of the current branch. It then launches Claude Code in a Docker container, mounts the worktree directory, and passes the prompt to Claude Code which will then execute the prompt until it's done. This is fantastic for autonomous development.
# Initialize a project
cd /path/to/your/project
iterare init
# Create a prompt
cat > .iterare/prompts/refactor.md << 'EOF'
---
workspace: refactor-auth
branch: main
---
Refactor the authentication module to use JWT tokens.
Add tests for the new implementation.
EOF
# Execute the prompt
iterare execute refactor
# Monitor progress
iterare log -f
# When done, merge changes back
iterare merge
# Clean up the worktree
iterare cleanup -y
Commands
iterare init [PATH]
Initialise a project for iterare. Creates the .iterare/ directory with configuration files and
a workspaces/ directory for git worktrees.
iterare init # Initialize current directory
iterare init /path/to/project # Initialize specific directory
iterare init --force # Overwrite existing configuration
iterare install
Create global configuration directories for credentials and logs.
iterare install
iterare credentials
Fetch Claude Code credentials via an interactive Docker session. Launches a container where you can log in, then extracts the credential files.
iterare credentials # First-time setup
iterare credentials --force # Re-authenticate
iterare credentials --image my-image:latest # Use custom image
iterare execute <prompt>
Execute a prompt in an isolated Docker container. Creates a git worktree, mounts it in a container, and launches Claude Code in autonomous mode.
# By prompt name (looks in .iterare/prompts/)
iterare execute refactor
# By file path
iterare execute .iterare/prompts/task.md
# Reuse an existing workspace
iterare execute refactor --reuse refactor-abc12345
# Pass environment variables to the container
iterare execute refactor --env PIP_INDEX_URL --env GITHUB_TOKEN
iterare interactive
Launch an interactive Claude Code session in a container. By default runs in the project directory without creating a worktree.
# Default: run in project directory
iterare interactive
# Create a worktree for isolation
iterare interactive --worktree
# Name the workspace
iterare interactive --worktree --workspace my-feature
# Base on a specific branch
iterare interactive --worktree --branch main
# Reuse an existing workspace
iterare interactive --worktree --reuse my-feature-abc12345
# Pass environment variables
iterare interactive --env PIP_INDEX_URL
iterare log [RUN_NAME]
View execution logs for a run.
iterare log # Most recent run
iterare log refactor-abc12345 # Specific run
iterare log -f # Follow live output
iterare log --raw # Raw JSON output
iterare log -v 0 # Minimal (text responses only)
iterare log -v 2 # Verbose (all details)
iterare list
List execution runs for the project.
iterare list # Active and finished runs
iterare list --all # Include cleaned up runs
iterare merge [RUN_NAME]
Merge a worktree branch back into the current branch.
iterare merge # Merge most recent run
iterare merge refactor-abc12345 # Merge specific run
iterare cleanup [RUN_NAME]
Remove the git worktree and branch for a run. Log files are preserved.
iterare cleanup # Clean up most recent run
iterare cleanup -y # Skip confirmation
iterare cleanup refactor-abc12345 -y # Specific run
Configuration
Project Structure
After running iterare init, your project will contain:
.iterare/
├── config.toml # Main configuration
├── Dockerfile # Custom Docker image (optional)
└── prompts/ # Prompt files
└── example-prompt.md
workspaces/ # Git worktrees (gitignored)
Config File (.iterare/config.toml)
[docker]
image = "iterare-llm:latest"
[session]
shell = "/bin/bash"
[claude]
credentials_path = "~/.config/iterare"
[firewall]
# Additional domains to allow through the firewall.
# Default domains (Anthropic API, GitHub, npm) are always included.
allowed_domains = [
"pypi.org",
"files.pythonhosted.org",
]
Prompt Files
Prompts are markdown files with optional YAML frontmatter:
---
workspace: my-feature
branch: main
---
# Task Description
Implement feature X by doing Y and Z.
Frontmatter fields:
- workspace -- Worktree directory name (defaults to prompt filename)
- branch -- Base branch for the worktree (defaults to current branch)
Environment Variables
Pass host environment variables to the container with --env:
export PIP_INDEX_URL="https://pypi.company.internal/simple"
iterare execute install-deps --env PIP_INDEX_URL
The flag accepts the variable name and reads the value from your shell. If a variable is not set, execution fails with an error.
Network Security
The container runs behind a whitelist-based firewall using iptables:
- All outbound traffic is blocked by default
- Only whitelisted domains are allowed (resolved to IPs via DNS)
- Default whitelist includes
api.anthropic.com, GitHub APIs, npm registry - Additional domains are configured in
config.toml
This prevents the autonomous agent from exfiltrating code or downloading malicious packages from unapproved sources.
Execution Flow
- Load configuration from
.iterare/config.toml - Parse prompt file (extract frontmatter metadata)
- Create git worktree on a new branch
- Write
.claude-auto-config.jsonand.claude-prompt.mdto worktree - Launch Docker container with worktree mounted at
/workspace - Container initializes firewall, then runs Claude Code autonomously
- Monitor via
iterare log -f - Merge results with
iterare merge, clean up withiterare cleanup
Development
make sync # Install dependencies
make test # Run tests (289 tests)
make coverage # Run tests with coverage report (100% coverage)
make lint # Check code style
make format # Auto-format code
Troubleshooting
Docker image not found
The default image (sohonet/iterare-llm:latest) is pulled automatically from Docker Hub.
To build locally instead:
make build
Container already running
docker stop it-<run-name>
docker rm it-<run-name>
Credentials not found
Run the credentials command to authenticate:
iterare credentials
Network blocked in container
Add the required domain to your config.toml:
[firewall]
allowed_domains = ["example.com"]
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file iterare_llm-0.2.0.tar.gz.
File metadata
- Download URL: iterare_llm-0.2.0.tar.gz
- Upload date:
- Size: 35.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a3474226c2a558b0129e0b5335564f69559e2e23adc16435087fe840618635d
|
|
| MD5 |
3fac050d24fabf845d57c9f45dddd810
|
|
| BLAKE2b-256 |
9e849883ef188fbb93e5e24793ae61eeee973742660acc5199cdfbd0e9300e2a
|
File details
Details for the file iterare_llm-0.2.0-py3-none-any.whl.
File metadata
- Download URL: iterare_llm-0.2.0-py3-none-any.whl
- Upload date:
- Size: 48.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ae0e50e4598aa5b5320f99f4c5d00818e8bf658f88432864cd4bf1370a1db82f
|
|
| MD5 |
c45a4273835931adcf6bb21c40f5cd14
|
|
| BLAKE2b-256 |
bcfda9a0ac721e962eb98d6027cfc50628ea3e0144a085707594c98fc49e0728
|