Search and summarize agent inboxes safely
编程
Mailgi — Free Email for Agents
试用Give an AI agent a real, deliverable email address. Register in one POST with no OAuth and no signup form, then send, receive, read and organise mail over a plain REST API — on a shared handle or your own verified domain.
它能做什么
Give an AI agent a real, deliverable email address. Register in one POST with no OAuth and no signup form, then send, receive, read and organise mail over a plain REST API — on a shared handle or your own verified domain.
技能文档
mailgi — SKILL FILE
This file teaches you how to use the mailgi email API. You are an AI agent. Read this file, then you can send and receive email.
Base URL: https://api.mailgi.xyz
Auth: Authorization: Bearer on all authenticated requests.
1. Get an email address
Register once. No password, no OAuth.
POST /v1/agents/register
Content-Type: application/json
{ "label": "my-agent" }
Response:
{
"agentId": "clxxx...",
"emailAddress": "buzzing-falcon@mailgi.xyz",
"aliasAddress": "x7k3mwf2qr5b@mailgi.xyz",
"apiKey": "amb_...",
"apiKeyId": "clyyy..."
}
Store apiKey immediately. It is shown exactly once.
emailAddress is your friendly address. Use it for sending and tell others to send to it.
aliasAddress is a deterministic alias — both receive mail to the same inbox.
2. Check your profile
GET /v1/agents/me
Authorization: Bearer
3. Read your inbox
GET /v1/mail
Authorization: Bearer
Optional query params:
mailboxId— filter to a specific folderlimit— max results (default 20, max 100)position— pagination offset (default 0)sort—ascordesc(defaultdesc)
Response: { messages: [...], total: N, position: N }
Each message has: id, subject, from, to, receivedAt, preview, seen.
Get full body of a message:
GET /v1/mail/
Authorization: Bearer
Response includes htmlBody and/or textBody. If body is a string, use it directly.
If it is an array of JMAP parts, look up bodyValues[part.partId].value for the text.
4. Send email
POST /v1/mail/send
Authorization: Bearer
Content-Type: application/json
{
"to": ["someone@example.com"],
"subject": "Hello from my agent",
"textBody": "Hi there."
}
Optional fields: cc, bcc, htmlBody, replyTo.
to, cc, bcc accept a single string or an array of strings.
Response: { "messageId": "..." }
Sending is free. Rate limit: 100 external emails per day per API key.
5. Manage mailboxes (folders)
List folders:
GET /v1/mailboxes
Authorization: Bearer
Each mailbox has id, name, role (inbox/sent/trash/drafts/etc), totalEmails, unreadEmails.
Create a folder:
POST /v1/mailboxes
Authorization: Bearer
Content-Type: application/json
{ "name": "Projects", "parentId": "" }
Move a message to a folder:
PATCH /v1/mail//move
Authorization: Bearer
Content-Type: application/json
{ "mailboxId": "" }
Mark as read:
PATCH /v1/mail//flags
Authorization: Bearer
Content-Type: application/json
{ "seen": true }
Delete a message (moves to Trash):
DELETE /v1/mail/
Authorization: Bearer
6. API keys
You can create additional API keys (e.g. one per task):
POST /v1/apikeys
Authorization: Bearer
Content-Type: application/json
{ "label": "task-runner", "expiresAt": "2026-12-31T00:00:00Z" }
Response includes apiKey (raw, shown once) and id.
List keys: GET /v1/apikeys
Revoke a key: DELETE /v1/apikeys/
7. DID-based auth (optional)
If you registered with a did:key: DID, you can authenticate without an API key:
- Request a challenge:
POST /v1/auth/challenge
Content-Type: application/json
{ "did": "did:key:z6Mk..." }
- Sign the returned
noncewith your Ed25519 private key (base64url), then verify:
POST /v1/auth/verify
Content-Type: application/json
{ "did": "did:key:z6Mk...", "nonce": "...", "signature": "" }
Response: { "token": "...", "expiresIn": 3600 } — use as Authorization: Bearer .
8. Error responses
All errors follow:
{ "error": { "code": "ERROR_CODE", "message": "Human-readable description" } }
Common codes:
401— missing or invalid API key404— message or mailbox not found409— conflict (e.g. mailbox name already exists)429— rate limit exceeded
9. Health
GET /health — liveness (always 200 if server is up)
GET /health/ready — readiness (checks DB + mail server)
Quick start (copy-paste)
# 1. Register
RESP=$(curl -s -X POST https://api.mailgi.xyz/v1/agents/register \
-H "Content-Type: application/json" \
-d '{"label":"my-agent"}')
EMAIL=$(echo $RESP | jq -r .emailAddress)
KEY=$(echo $RESP | jq -r .apiKey)
# 2. Send a message
curl -s -X POST https://api.mailgi.xyz/v1/mail/send \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d "{\"to\":[\"someone@example.com\"],\"subject\":\"Hi\",\"textBody\":\"Hello from $EMAIL\"}"
# 3. Read inbox
curl -s https://api.mailgi.xyz/v1/mail \
-H "Authorization: Bearer $KEY"
10. TypeScript / Node.js SDK
Install:
npm install @mailgi/mailgi
import { AgentMailboxClient } from '@mailgi/mailgi';
// Construct from a stored API key
const client = AgentMailboxClient.withApiKey(
'https://api.mailgi.xyz',
process.env.MAILGI_API_KEY!,
);
// Register a new agent (first time only — save the returned apiKey)
const reg = await client.agents.register({ label: 'my-agent' });
// reg.emailAddress => 'buzzing-falcon@mailgi.xyz'
// reg.apiKey => 'amb_...' (shown once — store it)
client.apiKey = reg.apiKey;
// Send email
const { messageId } = await client.mail.send({
to: ['someone@example.com'],
subject: 'Hello',
textBody: 'Hi from my agent.',
});
// Read inbox
const { messages } = await client.mail.list({ limit: 20, sort: 'desc' });
const email = await client.mail.get(messages[0].id);
console.log(email.subject, email.textBody);
// Mark as read
await client.mail.setFlags(email.id, { seen: true });
All SDK methods map 1-to-1 to the REST endpoints above. Errors extend AgentMailboxError with statusCode and code:
import { NotFoundError, UnauthorizedError } from '@mailgi/mailgi';
try {
await client.mail.get('bad-id');
} catch (err) {
if (err instanceof NotFoundError) console.error('Not found');
if (err instanceof UnauthorizedError) console.error('Bad API key');
}
11. CLI
Install globally:
npm install -g @mailgi/mailgi
All commands require --agent .
# Register a new agent (saves API key to ~/.mailgi/config.json)
mailgi register --label my-agent --agent me@mailgi.xyz
# Save an existing agent by API key
mailgi login --agent buzzing-falcon@mailgi.xyz --apikey amb_...
# List saved agents
mailgi agents
# Show agent profile (live from API)
mailgi me --agent buzzing-falcon
# Read inbox
mailgi inbox --agent buzzing-falcon
mailgi inbox --agent buzzing-falcon --limit 50
# Read a message (auto-marks as seen)
mailgi read --agent buzzing-falcon
# Send email
mailgi send --agent buzzing-falcon --to alice@example.com --subject "Hi" --body "Hello"
mailgi send --agent buzzing-falcon --to alice@example.com --subject "Hi" --body-file ./message.txt
# Delete a message
mailgi delete --agent buzzing-falcon
# Mailboxes
mailgi mailboxes --agent buzzing-falcon
mailgi mailboxes create "Projects" --agent buzzing-falcon
mailgi mailboxes delete --agent buzzing-falcon
# API keys
mailgi keys --agent buzzing-falcon
mailgi keys create --label task-key --agent buzzing-falcon
mailgi keys revoke --agent buzzing-falcon
# Config
mailgi config show
mailgi config set-url https://api.mailgi.xyz
# Remove saved agent
mailgi logout --agent buzzing-falcon --yes
# Raw JSON output (any command)
mailgi inbox --agent buzzing-falcon --json
Full interactive docs: https://api.mailgi.xyz/docs Machine-readable spec: https://api.mailgi.xyz/openapi.json
Support
Questions or issues? Email objective-crocodile@mailgi.xyz — yes, it's a real mailgi inbox.
相关技能
Operate the agent-email CLI to create disposable inboxes, poll for new mail, retrieve full message details, and manage local mailbox profiles. Use when the u...
Operate AgentMailer safely from the shell
Draft and deliver agent email with control
Read and write email through the Atomic Mail from an AI agent. Handles proof-of-work authentication and JMAP so the agent thinks in JMAP method calls. Use when the user asks to register an email inbox, list mailboxes, fetch or send email.
Create a human-approved AI agent identity