Headless Claude Code interaction via email
Project description
Airut
Headless Claude Code interaction via email. Named "Airut" (Finnish: herald/messenger).
Send an email with instructions, receive Claude Code's response. Airut runs Claude Code in isolated containers, maintains conversation state, and handles the full email-to-PR workflow.
You → Email → Airut → Claude Code (container) → PR → Email reply → You
Key Features
- Defense-in-depth sandboxing — container isolation, surrogate credentials, and network allowlist limit blast radius in case of agent misbehavior
- Email-native authentication — DMARC verification with sender allowlist, no API keys to manage
- Model selection via subaddressing — choose the model per email (e.g.,
airut+haiku@example.comfor fast/cheap,airut+opus@example.comfor complex tasks) - Conversation threading — reply to continue conversations across sessions
- File attachments — send files to the agent, receive files back
- Web dashboard — monitor running tasks and view network activity logs
Quick Start
Prerequisites
- Linux (dedicated VM recommended, Debian 13 tested)
- uv, Git, and Podman (rootless)
- Dedicated email account with IMAP/SMTP access
Install
# Install uv (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install Airut from PyPI
uv tool install airut
Or install the latest development version from main:
uv tool install airut --from git+https://github.com/airutorg/airut.git
Configure
# Generate initial config at ~/.config/airut/airut.yaml
airut init
# Validate config and system dependencies
airut check
Deploy
# Install and start the systemd service
airut install-service
# Verify it's running
airut check
Update
airut update
How It Works
Each email conversation runs in an isolated container with its own git workspace, Claude Code session, and sandboxed network. The recommended workflow has agents push PRs for your review — you review, leave comments, and reply to the email to iterate.
You: "Add user authentication"
↓
Agent: works → pushes PR → replies with PR link
↓
You: review PR, leave comments
↓
You: reply to email "Address the review comments"
↓
Agent: reads comments → fixes → updates PR → replies
↓
You: approve and merge
Sandbox Library
The airut.sandbox module is a standalone library for safe containerized
execution of headless Claude Code. It can be used independently of the email
gateway to run Claude Code in isolated containers from any Python application —
CI pipelines, automation scripts, custom integrations, or your own agent
orchestrator.
Core capabilities:
- Container lifecycle — two-layer image build, execution, and cleanup via Podman or Docker
- Network isolation — transparent DNS-spoofing proxy enforcing a domain
allowlist, with no
HTTP_PROXYenv vars oriptablesrules needed - Secret masking — surrogate credential injection so real secrets never reach the container, with proxy-side replacement on egress
- Event streaming — append-only log of Claude's streaming JSON output, safe for concurrent reads during execution
- Outcome classification — typed
Outcomeenum (success, timeout, prompt-too-long, session-corrupted, container-failed) so callers match on outcomes instead of parsing strings
Quick example:
from airut.sandbox import Sandbox, SandboxConfig, Mount, ContainerEnv, Outcome
sandbox = Sandbox(SandboxConfig())
sandbox.startup()
image = sandbox.ensure_image(dockerfile, context_files)
task = sandbox.create_task(
execution_context_id="my-run-1",
execution_context_dir=run_dir,
image_tag=image,
mounts=[Mount(host_path=repo, container_path="/workspace")],
env=ContainerEnv(variables={"ANTHROPIC_API_KEY": key}),
timeout_seconds=600,
)
result = task.execute("Fix the failing tests")
if result.outcome == Outcome.SUCCESS:
print(result.response_text)
sandbox.shutdown()
See the sandbox spec for full architecture details and API reference.
Documentation
Full documentation is available on GitHub:
- Deployment Guide — installation, configuration, and service management
- Architecture — system architecture and data flow
- Security Model — email auth, container isolation, credential handling
- Repo Onboarding — how to onboard a new repository
- Agentic Operation — email-to-PR workflow patterns
Links
License
MIT License. See LICENSE for details.
Project details
Release history Release notifications | RSS feed
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 airut-0.12.0.tar.gz.
File metadata
- Download URL: airut-0.12.0.tar.gz
- Upload date:
- Size: 884.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c559ec8460c71f39e7afa9d80f0bd85129ac1373bf614a0050e8c978b6c354a
|
|
| MD5 |
ca45c6f5ab6dfcc004d39a25b86899ac
|
|
| BLAKE2b-256 |
b6e9c44eaeb60ada29487eba6225262864706cec810332024c1bb3842b025b6a
|
Provenance
The following attestation bundles were made for airut-0.12.0.tar.gz:
Publisher:
publish.yml on airutorg/airut
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
airut-0.12.0.tar.gz -
Subject digest:
2c559ec8460c71f39e7afa9d80f0bd85129ac1373bf614a0050e8c978b6c354a - Sigstore transparency entry: 957451737
- Sigstore integration time:
-
Permalink:
airutorg/airut@e9c9cc0d9a53f74fbe9c84b30cb5f190e001227a -
Branch / Tag:
refs/tags/v0.12.0 - Owner: https://github.com/airutorg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e9c9cc0d9a53f74fbe9c84b30cb5f190e001227a -
Trigger Event:
release
-
Statement type:
File details
Details for the file airut-0.12.0-py3-none-any.whl.
File metadata
- Download URL: airut-0.12.0-py3-none-any.whl
- Upload date:
- Size: 234.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7cf93b7cf9fbd790681d886dfe2416b3bb662b3cc070ed1f34d3ea4203ad2884
|
|
| MD5 |
d0256249ca31179d2a1406d36a181e46
|
|
| BLAKE2b-256 |
d4294ffe7bdf6042cf857f056e3364fdb2c3faf9c3c28e56aae9a77bfaaf4bfb
|
Provenance
The following attestation bundles were made for airut-0.12.0-py3-none-any.whl:
Publisher:
publish.yml on airutorg/airut
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
airut-0.12.0-py3-none-any.whl -
Subject digest:
7cf93b7cf9fbd790681d886dfe2416b3bb662b3cc070ed1f34d3ea4203ad2884 - Sigstore transparency entry: 957452043
- Sigstore integration time:
-
Permalink:
airutorg/airut@e9c9cc0d9a53f74fbe9c84b30cb5f190e001227a -
Branch / Tag:
refs/tags/v0.12.0 - Owner: https://github.com/airutorg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e9c9cc0d9a53f74fbe9c84b30cb5f190e001227a -
Trigger Event:
release
-
Statement type: