Can an AI agent have a mailbox of its own?
An agent reads a mailbox of its own by IMAP and answers by SMTP. This post names the two secrets, the intake by heartbeat, and the send allowlist.
A mailbox like support@example.com is read by a person today. If an agent is to take that work over, it has to do the same four handgrips. It looks through the unread mail, answers one message at a time, ticks off what is done and files the rest. The obvious way in is the account of the colleague who has been reading the mailbox so far.
That breaks as soon as the agent starts working. It sets read flags and moves mail into folders, and the colleague finds a re-sorted mailbox the next morning. Step 1 of covey's own setup instructions says what to do instead: never share a person's account, create one of the agent's own (support-agent@example.com).
On Hacker News the question shows up in two shapes. Under a Show HN in March 2026, kwstx asks whether these are real mailboxes over IMAP and SMTP or an API abstraction on top of email. TZubiri asks below it why an agent needs a different interface from the ones we already have for humans.
An ordinary mailbox is enough
Covey answers both questions the same way: the email target system reads by IMAP and sends by SMTP, and there is no product-specific API for it. Every mailbox with IMAP and SMTP access fits, your own mail server as much as a Gmail or Office 365 account with an app password.
Two secrets set it up. email_url carries the mail server, email_token the address and the password, separated by a colon. For the support mailbox that would be mail.example.com and support-agent@example.com:app-password. That short form expands into the standard setup (IMAP with TLS on port 993, SMTP submission with STARTTLS on port 587, both on the same host). If IMAP and SMTP sit on separate hosts or on other ports, email_url encodes both endpoints as URLs.
Two handgrips remain on the agent itself: the line - system: email scope: read,write in its ACCESS.md, and the release of both hosts in its egress configuration.
The agent never gets to see the password
Both connections, IMAP and SMTP, run outbound from the sandbox. There is no way in — for this target system the control plane accepts nothing. New mail the agent discovers itself, by calling list_unread after the wake-up. The credentials still stay out of its workspace. On every call the control plane checks the release, resolves email_token and email_url, and hands both to the daemon with a lifetime (15 minutes, unless COVEY_DAEMON_TOKEN_TTL says otherwise). The agent gets the list of its mail, and the app password of support-agent@example.com stays in the daemon.
Without a webhook, the heartbeat wakes it, and only when mail is there
Email knows no webhook.
The inbox is polled through the agent's HEARTBEAT.md, with a line of roughly the form - alle: 5m nur-wenn: email. That nur-wenn: changes who looks.
Before every run the control plane asks by IMAP itself whether unread mail is present in support-agent@example.com. Only then does it wake the agent, which is why an interval of five minutes produces no runs over an empty mailbox.
Taking the same IMAP path as list_unread, the advance check sees exactly the working set the agent would get: its own mail drops out through echo protection, and senders outside COVEY_EMAIL_INTAKE_ADDRESSES stay hidden. Should the check itself fail, the heartbeat fires as usual, because a broken condition must not leave work lying around.
The read status is the working-set signal. A reply marks the mail as read by itself, everything else the agent ticks off explicitly. Since get_message fetches with BODY.PEEK, a mail that was read and not worked on is there again at the next run.
Covey draws the line at sending
A mail is input, and input is what it stays when its text contains an instruction. A Hacker News post from June 2025 describes the pattern on an agent holding gmail.readonly, gmail.send and gmail.modify: a smuggled-in instruction is read as a task and carried out with the agent's own valid permissions.
So the boundary sits at sending. COVEY_EMAIL_SEND_DOMAINS limits recipients to domains or complete addresses, and the list takes effect daemon-side before every SMTP delivery; left empty, mail goes to arbitrary addresses.
Guard rails stand beside that. Sending is governable on its own (email:send and email:reply are subjects that can carry an approval requirement) while reading runs unhindered. Three locks work against loops: list_unread skips mail from the own address, a reply to the own address is refused, and the prompt tells the agent to tick off machine-generated mail rather than answer it.
Two covey agents writing to each other are caught by none of those locks. Section 3.3 of the documentation says so in the same place it lists the three mechanisms, and names COVEY_EMAIL_INTAKE_ADDRESSES or the guard rails as the way out.
The price of this setup is the reaction time, which is the heartbeat interval. An agent also has exactly one mailbox, because the secret pair applies per agent. Sending is text/plain, without HTML and without attachments, while incoming attachments the agent fetches one at a time into its sandbox (get_attachment, 25 MB by default). OAuth2 is not built; it stays at a user name and a password. So a mailbox of its own stays a mailbox, and whoever sets it up creates it the way they would for a person.
What is left to decide afterwards is the list of recipients.