OpenClaw
agentpost runs as a native channel in OpenClaw: inbound mail arrives as a direct-message conversation, and the agent's reply goes back into the same email thread.
agentpost is in closed preview - request access first.
Requires Node 22.22.3+, 24.15+, or 25.9+, which is OpenClaw's own floor.
Install
openclaw plugins install npm:@agentpost-no/openclaw --accept-capabilitiesIf you would rather not install from npm, every release also carries the built tarball. Download it from the releases page and install the file:
openclaw plugins install ./agentpost-no-openclaw-0.1.0.tgz --accept-capabilitiesOpenClaw cannot install a plugin from a git URL - its installer accepts npm specs, local paths and archives only.
Configure
openclaw config set channels.agentpost.username claude
openclaw config set channels.agentpost.ownerEmail you@example.com
openclaw config set channels.agentpost.allowFrom '["you@example.com"]' --strict-jsonThen start the gateway. On first run the plugin registers the address and emails the owner a verification link; the channel connects by itself once that link is clicked, retrying every 30 seconds in the meantime.
| Key | Meaning |
|---|---|
username | Local part of the address. claude gives claude@agentpost.no |
ownerEmail | Owner. Receives verification, approval requests and status notices |
displayName | Name in the From field. Defaults to the capitalized username |
allowFrom | Senders allowed to reach the agent |
dmPolicy | allowlist (default) or open |
home | Storage root. Defaults to <stateDir>/agentpost/<accountId> |
accounts | Named extra identities, same keys as above. Only one runs at a time today; the plugin refuses a second rather than share one mailbox between two keypairs. |
Anyone can write to an email address, so unknown senders are rejected until the owner lists them. Each account gets its own storage root, because the keypair is the identity.
Inbound informs, sending is deliberate
Inbound mail is not a thread you answer by talking. Nobody sits in an agentpost conversation: you talk to your agent where you already do - Telegram, WhatsApp, the web chat - and an arriving email surfaces in that same session.
Replying is a tool call:
| Tool | For |
|---|---|
agentpost_send_email | A new email: subject, body, optional HTML alternative, attachments, on-behalf-of, footer language |
agentpost_reply | A reply inside an existing thread, keeping its subject and In-Reply-To chain |
agentpost_check_inbox | Unread mail and notices, for when the gateway was down |
The alternative - delivering whatever the agent said in that session straight back to the sender - would mean a remark meant for you leaves as mail, and instructions smuggled into the email being answered get an unattended path out. Sending is an act, not a side effect.
How mail flows
Inbound: the worker pushes the sealed message over an authenticated WebSocket, the plugin decrypts it locally, wraps it in untrusted-content markers, and dispatches it as a DM from the sender's address. Attachments land under <home>/attachments/. The message is acknowledged only after it is durable locally, so a crash cannot lose mail.
Outbound: agentpost_reply goes back through the worker into the same thread with In-Reply-To preserved. A new conversation takes the subject you give it. The worker holds each outbound message for owner approval unless that contact is already trusted.
Delivery reports and approval results arrive as a DM from ownerEmail, so the agent learns when its mail actually went out. A reply to one of those notices is never sent: that return path is a loop, because every email it sends produces another delivery report. The client also refuses to send to its own address and caps itself at eight sends per minute.
Verify
openclaw channels statusA working channel reports enabled, configured, running, connected with the address beside it.
MCP instead of a channel
If you want the tools but not a channel, the same client runs as a plain MCP server:
openclaw mcp add agentpost --command node --arg /path/to/plugins/agentpost/dist/server.node.mjsThat gives register_email, send_email, reply_to_email and check_inbox. Inbound mail is then pulled with check_inbox rather than pushed into a conversation. Set AGENTPOST_HOME to keep that host's keys out of ~/.claude.