Skip to main content

@gent

Email an idea. Your coding agent gets to work.

Send a task from your phone. Codex or Claude Code runs on your own computer and emails you the result. Reply to continue the same session. Run each task in the background or in a Terminal window, chosen in the subject line or by a default you configure.

No SSH, mobile terminal app, port forwarding, or public endpoint. Repositories and agent sign-ins stay on your computer; task text and results travel through Gmail and your chosen agent provider.

Requirements: Gmail or Google Workspace with IMAP access, macOS/Linux, Python 3.11+, and uv. macOS is live-tested; Linux has automated coverage. Your computer must stay awake and online. Install and sign in to Codex or Claude Code first; Claude needs the --permission-prompts option (v2.1.259+). Existing subscriptions, limits, and permissions apply.

Send a task

To: you+agents@gmail.com
Subject: Codex: improve the signup form

Find the confusing parts of the signup form, improve them,
and run the relevant checks. Leave the changes ready to review.

Choose Claude Code with Claude: your task. Target a configured project with Codex/website: your task. Pick a model for one task by putting its name in square brackets before the colon:

Claude [opus]: review the auth flow
Codex/website [gpt-6.1-sol]: fix the build
Claude/mailbox [haiku]: summarise the open issues

The model applies to every reply in that thread and to a local resume. Without brackets the agent's default model from the config is used. Model names may contain letters, numbers, ., _ and -; any other subject is ignored. Agent names are case insensitive; project aliases are case sensitive.

Headless or Terminal

A task runs headless by default: the agent works in the background and emails the result. Put terminal in the same brackets to open that task in a new Terminal window instead, with an interactive agent session you can type into:

Claude [terminal]: set up the staging branch
Claude/mailbox [opus, terminal]: review the auth flow
Codex [headless]: fix the build

The subject wins over the config. Set the default with atgent mode terminal (every agent) or atgent mode terminal claude (one agent); atgent mode headless goes back. atgent init asks the same question. For Claude terminal tasks, atgent remote-control on starts the session with Remote Control so you can continue it from your phone or the web.

A terminal task finishes its email turn as soon as the window opens; the agent's output stays in the window. Claude terminal sessions get a known session id, so atgent open TASK_ID and later replies resume them. Codex terminal sessions are not tracked, so replies start a new window. Terminal mode uses osascript on macOS and x-terminal-emulator, gnome-terminal, konsole or xterm on Linux. Email approvals do not apply: the interactive agent asks in its window. Claude uses --dangerously-skip-permissions there only when claude_permission_mode is bypassPermissions.

You'll receive Queued, Started, and a result in the email thread. Reply with your next instruction to continue the exact session. Reply status for progress or stop to cancel queued turns and stop the running process. File changes already made are retained.

Plain text and HTML-only email are accepted. Write replies above the quoted conversation. HTML is converted to text without executing active content; recognized quoted threads are removed. Attachments are saved under the task's private local state directory and their paths are included in the agent prompt. Attachments are untrusted input and are not automatically executed.

Default limits: 20 MiB per raw message, 5 MiB per attachment, 10 MiB combined attachments, 10 attachments, and 32,000 characters of task text. Oversized or unsupported nested attachments cause the message to be ignored. Byte/count limits can be lowered with max_message_bytes, max_attachment_bytes, max_attachments_bytes, and max_attachments.

Install

With uv installed:

uv tool install atgent
atgent init

The old agent-mailbox command still works and runs the same program.

init asks for your Gmail address, how the runner signs in (app password from the Keychain, a command or an environment variable, or your own OAuth client), your project folders, and which installed agents to use with their default models. It writes ~/.config/agent-mailbox/config.json without any secret, offers to run doctor, then recommends enabling automatic startup after the checks pass. Accept that prompt to keep intake running after login and recover after process failures. For a script, atgent init --email you@gmail.com --project /absolute/path/to/project writes a minimal config without questions.

Change an agent's default model later with atgent model claude opus, or atgent model codex default to return to Codex's own default.

Choose an app password or your own Gmail OAuth desktop client. An app password is simpler when your account permits it. Follow Google's app-password setup. Managed accounts and some security settings block app passwords; OAuth can still require administrator consent. The OAuth alternative is documented in Gmail sign-in.

Keep the password in your password manager or OS keychain. In ~/.config/agent-mailbox/config.json, set password_command to an argument array. For example, after storing the password in a macOS Keychain item named atgent:

"password_command": ["security", "find-generic-password", "-s", "atgent", "-w"]

Alternatively set AGENT_MAILBOX_PASSWORD in your environment for a foreground or detached runner. Login services do not inherit your interactive shell environment; use a keychain/password-manager command for automatic startup, or explicitly configure the service manager to supply required environment variables. The generated config references that variable, never the password. A password command takes priority. Don't put literal passwords in command arguments or commit local configuration.

atgent doctor
atgent install-service
atgent service-status

doctor first reports whether the runner is stopped and whether automatic startup is installed. It authenticates IMAP and SMTP without sending mail and checks CLI installation. It exits nonzero if any configured agent fails its version probe, is missing, or times out; every configured agent is checked. It does not prove agent sign-in or remaining capacity. On the first successful poll, the runner skips historical Sent mail and arms new-message intake. Send your task after this happens.

To run detached without opening a window:

atgent start
atgent status
atgent shutdown

Without an installed service, this is an ordinary process with no automatic login/reboot persistence. When a service is installed, start resumes and refreshes that service instead. Logs and private state are under state/ beside your config. Detached startup checks for an immediate child-process failure and identifies its log; neither startup mode guarantees mailbox readiness. The log records Mailbox intake armed; runner ready after a successful poll. status includes runner liveness and whether a service file is installed; an installed file alone does not prove a running service. Use service-status to check the supervisor.

atgent shutdown
atgent install-service
atgent service-status
atgent uninstall-service

Installation registers a user LaunchAgent on macOS or a systemd user unit on Linux. The service starts at user login and recovers after unexpected exits, including exit code zero and termination signals. macOS uses KeepAlive=true; Linux uses Restart=always. Both limit restart frequency to once every 30 seconds. Recovery is part of the installed app service and requires no separate monitoring script.

atgent shutdown stops through the service manager so an intentional stop stays stopped for the current login session. atgent start resumes an installed service through the manager instead of creating a competing detached process. atgent stop-service and atgent start-service provide the same service controls directly. atgent uninstall-service stops the service and removes automatic startup permanently. These commands retain the config and task history; they do not undo task changes. A shared process lock prevents a second runner.

After upgrading the CLI, run atgent start to refresh the existing service and resume intake. atgent install-service can also refresh an existing registration. The app preserves the queue, intake cursor, configuration and service environment. Shut down an ordinary, unsupervised runner before installing a service. Refresh a running service when its tasks are idle: restarting marks active turns interrupted and holds their queued follow-ups for review rather than replaying them. Older installed versions do not acquire the new recovery policy until their package and service registration are updated.

Initial mailbox connection failures and later mail errors are retried without exiting. An unexpected worker-thread exit fails the runner so its service can restart it. The durable intake cursor catches up on mail received while offline; restarting does not rebaseline or skip that backlog. Interrupted running tasks are recovered without automatically replaying their changes. Readiness is reported separately from process liveness: atgent status --human --wait-ready 30 verifies intake after startup.

Linux startup before login requires user lingering configured separately. macOS does not run the job before login. Keep the Python installation, config path, CLI executables, and credential resolver available at the same paths. The computer must remain awake and connected. Installing the CLI alone does not start a runner; use guided setup or install the service explicitly.

Projects and permissions

Only configured project aliases can be selected. Edit your local config:

"projects": {
  "main": "/absolute/path/to/project",
  "website": {
    "path": "/absolute/path/to/another/project",
    "sandbox": "read-only",
    "agents": {
      "codex": {"approval_policy": "on-request", "approvals": "email"}
    }
  }
},
"default_project": "main"

Set max_workers to run tasks concurrently (default 1, maximum 32). By default each project directory runs one task at a time, including aliases that resolve to the same directory. Set "concurrent": true on a project ("lab": {"path": "/absolute/path", "concurrent": true}) to let separate tasks run side by side in it, for example a folder that holds many repositories. Turns in the same thread or session always run one at a time. The runner does not coordinate other local editors or separately launched agents, and concurrent tasks in one directory can edit the same files.

Codex settings can be global (codex_sandbox, codex_approval_policy), per agent (agents.codex.sandbox / approval_policy), per project, or per project-agent as above. Precedence is project-agent, project, agent, global, then defaults. Sandboxes are read-only, workspace-write, or danger-full-access; approval policies are never, on-request, untrusted, or on-failure, subject to installed CLI support. approvals can likewise be overridden by agent/project. Choose elevated access deliberately.

With approvals off (the default), Codex uses workspace-write and doesn't wait for approval prompts. Set codex_sandbox to read-only for a read-only baseline. Existing Codex/project instructions still apply; sandboxing isn't bypassed. Privileged or network-dependent work may be blocked by CLI policy.

With approvals off, Claude uses dontAsk by default. It permits Read/Edit/Write/Glob/Grep/Bash/WebFetch tools and denies actions that require interactive approval because no one is present to answer a prompt. The runner provides no OS sandbox for Claude. Bash runs with the same access as an ordinary local session, bounded only by the configured project directory and whatever rules exist in Claude's own settings. Project selection sets Claude's working directory, not a filesystem security boundary. If a turn finishes with denied requests, its status is needs_review, and completed work remains.

Set "claude_permission_mode": "bypassPermissions" globally, per agent, per project, or per project-agent. It uses the same precedence and keys as the Codex settings above. This setting stops dontAsk from denying actions during a task. It runs Claude with --dangerously-skip-permissions, which allows every tool call without a prompt or per-call review, including calls that dontAsk would otherwise deny. It is the only setting that removes the denials caused by this mode, and no narrower setting exists. Config validation rejects combining it with "approvals": "email" because full bypass conflicts with human-reviewed actions. Choose it deliberately, and prefer scoping it to one trusted project instead of using the global default.

Existing CLI sign-ins are reused. Inherited provider API-key variables are removed; explicit agent env entries can opt in. No subscription is created and there is no silent fallback to another agent. For an existing Claude account, set CLAUDE_CONFIG_DIR in agents.claude.env. Keep that account stable across replies.

Approve actions by email (optional)

Add this to your local configuration and restart the runner when no task is active:

"approvals": "email",
"approval_timeout_seconds": 900

When the CLI needs permission, the same running turn pauses. An email displays the complete native action, working directory, reason, task and turn identifiers, and a SHA256 digest. Reply directly to that approval email with approve or deny, or in its task thread with exactly approve TOKEN or deny TOKEN. Ordinary replies and quoted messages never count as approval. You can still send status or stop while waiting.

A grant applies to one concrete request, never a session or future command. Wrong-thread, expired, duplicate, cancelled, and restart-invalidated decisions cannot authorize it. No answer means denial after the timeout. The runner keeps reading mail while the agent waits and never restarts the task to implement approval. Previously completed external actions are not replayed. Native policies may still block an approved request.

Codex uses its native stdio app-server with on-request approval policy and the configured sandbox. Commands already permitted by that sandbox may run without an email; use "codex_sandbox": "read-only" for a stricter baseline. File-change requests need a complete native diff; requests for session-wide root grants, terminal input, unsupported permission types, and actions too large to display fully are refused.

Claude uses its native stream-json host permission channel with default mode. Existing allow rules can run without a new email; hard deny rules remain enforced. No broad tool allowlist is added in email mode. This is a bundled protocol adapter: no separately installed agent plugin or phone app is required. Use a current CLI supporting host permission prompts (Claude Code v2.1.259+ and Codex app-server). If the native channel is unavailable, the turn fails closed rather than falling back to bypass permissions.

Set "approvals": "off" to retain the original noninteractive behavior. This option does not enable bypass mode, change global CLI settings, or remove existing hooks. See approval behavior and limits.

Pick up locally

atgent list            # pick a session with the arrow keys, Enter opens it here
atgent open TASK_ID    # resume one task's session in this terminal

Each row shows the agent, the model, the turn status, how long ago it last ran and the subject; the bottom pane previews the selected task's last reply. Press / to filter, Esc to clear the filter, and q to quit. The session opens in its project directory with the agent's configured environment and model, so Claude sessions that use their own CLAUDE_CONFIG_DIR resume correctly. The resumed agent is told that you are now in the terminal, so it answers there instead of by email. If the task is still running from email, list and open ask whether to stop it first, then wait for the runner to release the session. atgent pickup TASK_ID prints the plain resume command without running it. Pause the runner during an extended local handoff; don't run local and email turns simultaneously against the same session.

Reliability and trust

  • Intake reads Gmail's authenticated Sent special-use folder, not Inbox. A spoofed incoming sender can't submit a task. Anyone able to append to your Sent folder has equivalent task-submission authority; protect your Gmail account and app password.
  • Task messages must be authored by the mailbox owner and addressed to the task alias. Automatic notifications are excluded to prevent loops.
  • Message IDs are deduplicated in SQLite. References map replies to exact sessions. Unmatched replies never become new tasks.
  • Configured workers run different project directories concurrently. The scheduler serializes each project directory and session within this runner.
  • An exclusive process lock prevents a second runner. Interrupted turns are held rather than replayed. Recorded orphan process groups are stopped only after matching PID and OS start time. A small crash window exists between process creation and identity recording; inspect the machine after an unclean shutdown.
  • SMTP sends with uncertain acceptance aren't blindly resent. status shows delivery state; check Sent mail as needed. A task can finish even when its notification fails.
  • A Sent-folder UID reset pauses intake. Shut down, review pending mail, then explicitly skip historical mail with atgent rebaseline.
  • Local state contains prompts, attachments, approvals, and results and is created with private permissions. Agent session transcripts follow their CLI's normal retention policy. Neither should be shared in bug reports.

There is no hosted inbox, mobile live-terminal UI, or remote browser-authentication handoff in this version. Email approvals authorize one displayed action; approve all is unsupported. Review work before publishing or deploying it.

First task and local status

After setup and startup, run atgent status --human --wait-ready 30. This waits up to 30 seconds for a fresh readiness marker from the active, lock-owning runner. A registered service, stale PID or earlier process's marker is not sufficient. Intake states are starting, ready, blocked, unknown and stopped. A failed mailbox poll marks intake blocked; a later successful poll restores readiness. No account, message or credential content is written to the readiness marker. Version probes still do not prove agent sign-in or remaining capacity.

Run atgent compose for a guided local draft using the existing setup prompts. Choose a configured agent/project and type a title and instruction. It prints To, Subject and body; it never opens a mail app or sends a message. Noninteractive use:

atgent compose --agent codex --project main --title 'Explain checks' --body 'Explain how to run checks. Do not change files.'

Send the draft yourself only after intake is ready. The first poll skips historical Sent mail. atgent status --human separates recent task outcomes from notification delivery; the default status command remains JSON. An uncertain SMTP acceptance is not a reason to rerun a completed task or blindly resend its email. atgent list includes project names in its existing picker and filter. Reply footers link to the local status command as well as the terminal resume command.

Docs and support

Anonymous usage counts

The CLI sends best-effort lifecycle counts to PostHog: first execution, setup start/completion, mailbox verification, runner activation, first task start/completion and coarse failure categories. Terminal launches are counted separately because the runner cannot observe their completion. An anonymous random ID is stored in the configuration's state/analytics.json; each configuration has its own ID. No email addresses, task content, file paths, agent output or credentials are sent. IP geolocation and person profiles are disabled. A notice appears on first execution.

Set ATGENT_TELEMETRY=off or DO_NOT_TRACK=1 before running any command to disable these counts, including identity creation. CI is excluded. Network failures never fail a command; sends run in a background thread with a 0.5-second request timeout and at most 0.7 seconds of shutdown waiting. Counts can be lost when offline or during shutdown. This measures activated configurations, not package installs or unique people. Downloads, copied install commands and website visits are separate signals and cannot be joined to the CLI's anonymous ID.

Metadata

Release files for atgent 0.4.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for atgent 0.4.5
File Size Uploaded Provenance
atgent-0.4.5.tar.gz 104.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for atgent 0.4.5
File Interpreter ABI Platform
atgent-0.4.5-py3-none-any.whl Python 3 none any Details

Total release size: 163.4 kB

Release files / atgent-0.4.5.tar.gz

Download URL atgent-0.4.5.tar.gz
Size 104.2 kB
Tags Source
SHA-256 checksum
How to use checksums
21b0cf13fb72bd7dd47cf3ce93cff2ed8d02967e406b1461f3f3799de83f2388
BLAKE2b-256 checksum
How to use checksums
1015bc0db6e2c234666f9efef87fd374de37d44e0dd1604e63736240cfcd0b39
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","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}

Release files / atgent-0.4.5-py3-none-any.whl

Download URL atgent-0.4.5-py3-none-any.whl
Size 59.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e36e02c4f0f4d089bfcfb05f49e98eb6e3afa799d9478b428837c4f4a8957bad
BLAKE2b-256 checksum
How to use checksums
54061ab0ef465b33cb81bdb7f491ffd46e07d7756e221860afec89c20d6f6f8a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","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}

Security for atgent 0.4.5

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page