// MCP server · Open source · AGPL

Email infrastructure
for the agentic era

Cereal exposes a clean MCP interface to privacy-first, bowl-isolated email. Your agents read, send, and triage. Scoped to exactly the business identity you authorize. Nothing bleeds.

cereal-agent.ts · MCP session
// Connect Cereal as an MCP server const cereal = await connectMCP({ url: "https://localhost:3847/mcp", scope: "bowl:agency", // scoped, not global }); // Agent reads. Only sees the Agency bowl const threads = await cereal.read_inbox({ bowl: "agency", unread_only: true, }); // Agent sends. Identity enforced by bowl await cereal.send_email({ from: "auto", // resolves to agency identity to: "client@example.com", body: generatedReply, }); // Notify human via Cereal agent channel await cereal.notify({ message: "Sent proposal to Sarah. Awaiting reply.", }); ✓ Done . All actions logged

Giving an agent access to email
means giving it access to everything

There's no primitive for bowl-scoped email access. So agents get too much, or none at all.

problem_01.ts

No business-scoped email primitive exists

Every email API treats accounts as the access unit. But accounts don't map to business contexts. One business might span three accounts and four aliases. There's no clean abstraction for agents to use.

problem_02.ts

IMAP infrastructure is weeks of work before agents do anything

Connection pooling, IDLE listeners, credential encryption, sync state, UID tracking. All this before your agent reads a single email. Cereal is that infrastructure, already built and open source.

problem_03.ts

Agent email actions are invisible and unaudited

When an agent sends via raw IMAP, nothing logs it, nothing surfaces it, nothing lets you review it. The human oversight layer doesn't exist. Cereal's agent channel and audit trail close this gap.

Local-first IMAP.
Clean MCP on top

On self-hosted, Cereal's IMAP sync engine runs entirely on your machine. Credentials never touch our servers. On Hosted Pro, we connect on your behalf but never store email bodies permanently. Either way, the MCP server exposes the same typed, bowl-scoped interface.

01

Self-host or use hosted Cereal

Run the Docker image on your own infra, or use the hosted version. Either way, IMAP credentials stay local. Only agent channel traffic touches our servers on hosted Pro.

02

Connect via MCP

Point your agent at Cereal's MCP endpoint with a scoped API key. The key limits access to one or more bowls. The agent can't see outside its scope. By architecture, not policy.

03

Agents operate. You supervise.

Every action is logged to the audit trail. Review activity in the Cereal dashboard or agent channel, one place, full visibility, without touching raw email.

cereal.config.ts TypeScript
// cereal.config.ts: self-hosted setup import { defineConfig } from '@cereal/core' export default defineConfig({ // IMAP accounts: stay local, always accounts: [ { id: 'agency-main', provider: 'fastmail', user: 'hello@agency.com', pass: process.env.FASTMAIL_PASS, }, { id: 'saas-support', provider: 'zoho', user: 'support@saas.io', pass: process.env.ZOHO_PASS, }, ], // Bowls: the business abstraction layer bowls: [ { id: 'agency', accounts: ['agency-main'], color: '#ff6b35', // orange loop }, { id: 'saas', accounts: ['saas-support'], color: '#3a86ff', // blue loop }, ], mcp: { port: 3847, apiKeys: [{ key: process.env.AGENT_KEY, scope: ['agency'], }], }, })

A typed interface your
agents actually want

No raw IMAP. No credential management. Clean tools that do exactly what they say, scoped to the bowl you authorized.

read_inbox
(bowl: "agency", unread_only?: boolean)
Returns normalized thread objects from the specified bowl. Never returns threads from other bowls, regardless of how IMAP accounts are structured underneath.
send_email
(from: "auto" | address, to: string, body: string)
"auto" resolves to the default identity of the authorized bowl. The agent cannot send from an identity outside its scope. The server rejects it at the query level.
search_threads
(query: string, bowl: string, date_range?: DateRange)
Full-text search within a bowl. Powered by local IMAP search. No data leaves the machine.
notify
(message: string, urgency?: "low" | "normal" | "high")
Sends a message to the human via Cereal's agent channel. Not email, not Telegram. A proper notification inside the dashboard.
await_decision
(question: string, options: string[], timeout_ms?: number)
Pauses the agent and surfaces a decision in the dashboard. Resumes on human response. The missing primitive for supervised autonomy.
🔐

Architectural scope, not filter-based

API keys are issued with a scope field listing permitted bowls. The MCP server enforces this at query construction, not as a post-fetch filter. There's no way to leak data from another bowl.

📋

Full audit trail, always

Every tool call is logged: what the agent read, sent, flagged. Visible in the Cereal dashboard. Exportable. No action is invisible.

Zero IMAP infrastructure to build

Connection pooling, IDLE listeners, credential encryption, UID tracking, already built. You write the agent logic, not the email plumbing.

🌐

Any IMAP provider

Gmail personal, Google Workspace, Outlook and Microsoft 365, and any hosting provider's mail service: GoDaddy, Squarespace, Namecheap. If it speaks IMAP and SMTP, your agents can use it through Cereal.

🥣

Multiple agents, isolated bowls

Run a customer support agent for Bowl A and a lead-monitoring agent for Bowl B. Each scoped, each unaware of the other, each with its own API key.

Agency agent ● active
AI
Processed 7 unread in Agency bowl. 2 need you. Drafted replies for both. Review before I send?
You
Show me Sarah's first
AI
Sarah wants to move the Q3 kickoff to Thursday. I drafted: Thursday works. 2pm or 4pm? Send from hello@agency.com?
You
Send it
AI
✓ Sent and logged. Moving to Marcus. Invoice question. This one needs your judgment, not mine.
Reply to agent...

Your agents need a home.
Not Telegram

Built into the Cereal dashboard. Notifications, decisions, confirmations. A proper back-and-forth in the same place you manage everything else.

01

Bidirectional, not just pings

await_decision pauses execution until you respond. Real supervised autonomy, not one-way broadcast.

02

Context-linked, not decontextualized

Agent messages know which bowl they belong to. "Sent email from Agency" links directly to the thread. One click to review the full context.

03

E2E encrypted. The only part on our infra

Agent channel messages are end-to-end encrypted between your agent and your dashboard. We carry ciphertext. We can't read the messages.

Read the code. Fork it.
Self-host it. Forever free

Privacy claims are meaningless without verification. The entire Cereal stack is on GitHub.

📦

Full codebase on GitHub

IMAP sync engine, MCP server, dashboard, agent channel, all published. No private modules, no obfuscated sections.

github.com/cereal-app/cereal
⚖️

AGPL licensed

Anyone running a modified version as a hosted service must open source their changes. Keeps the ecosystem honest.

AGPL-3.0
🐳

Docker-first self-hosting

One docker compose up spins up the full stack on your own infra. On self-hosted, credentials and email never touch our servers. Everything is local.

docker compose up

Self-host free. Pay for
the managed layer

Self-hosted
$0
AGPL · Forever free
  • Full IMAP sync engine
  • MCP server with all tools
  • Bowl isolation
  • Agent audit trail
  • Full dashboard
  • Docker image
  • Community support
Star on GitHub →
Most popular
Hosted Pro
$9/mo
or $79/year, or $99 lifetime (first 500)
  • Everything in self-hosted
  • Managed, no DevOps
  • Cloud sync across devices
  • Mobile app
  • Hosted agent channel (E2E)
  • Priority support
  • Unlimited bowls & accounts
Join the waitlist →
Enterprise
Custom
Air-gapped · SLA · Dedicated infra
  • On-premise deployment
  • Air-gapped environments
  • Custom SLA
  • SSO / SAML
  • Dedicated support
  • Audit log exports
Contact us →

Technical questions,
straight answers

Does the MCP server have access to my email content?

It depends on which version you run. On self-hosted: the MCP server runs on your machine, IMAP connects directly from your device, and nothing passes through any server we control. On Hosted Pro: email passes through our servers in transit so we can serve the web app, but bodies are processed in memory and never stored permanently. Metadata (sender, subject, date) is stored encrypted so the app stays fast. Either way, the MCP tool interface is identical.

How does bowl-scoped authorization actually work?

API keys include a scope field listing permitted bowl IDs. The MCP server validates scope on every tool call before executing. The query is constructed with scope as a hard constraint, not a filter applied after fetching. An agent scoped to ["agency"] literally cannot construct a query that touches the saas bowl.

What IMAP providers work?

Any provider supporting IMAP4 with SSL/TLS: Gmail, Google Workspace, Outlook, Microsoft 365, GoDaddy, Squarespace, Namecheap, and custom domain mail. If the provider exposes IMAP, your agents can use it through Cereal. OAuth2 is handled automatically for Gmail and Outlook.

Can I run multiple agents against the same Cereal instance?

Yes. Issue separate API keys with separate bowl scopes. A support agent for Bowl A and a lead monitor for Bowl B run simultaneously, each unable to see the other's context. Each gets its own audit log stream.

What does AGPL mean in practice?

You can use, modify, and self-host Cereal freely. If you distribute a modified version or run it as a hosted service for others, you must open source your modifications under AGPL too. Running Cereal internally for your own agents has no open-source obligation.

Email infrastructure
agents can actually trust

Local-first, bowl-scoped, fully auditable. Everything the agentic era needs from email.