Browse by type
Auth Inbox is an open-source, self-hosted email verification code platform built on Cloudflare's free serverless services. It automatically processes incoming emails, filters out promotional mail before hitting the AI, extracts verification codes or links, classifies each mail, and stores everything in a database. A modern React dashboard with account login lets an admin manage everything, while regular users only see the mails an admin has granted them. AI agents can read the inbox too, through a built-in remote MCP server.
Don't want ads and spam in your main inbox? Need a bunch of alternative addresses for signups? Want your AI agent to complete sign-up flows by reading OTPs on its own? Try this secure, serverless, lightweight service!
flowchart LR
A([Your Inboxes]) --> B[Email Worker]
B --> C{Promotional?}
C -->|Yes| D[Save raw only]
C -->|No| E[AI Extraction + Category]
E --> F[(D1 Database)]
F --> G[React Dashboard]
F --> H([Bark iOS Push])
F --> I[Remote MCP Server]
I --> J([AI Agents])
List-Unsubscribe, Precedence: bulk, etc.) before calling the AI — saves tokens.login_code, registration, password_reset, account_security, payment, other).wait_for_code tool that blocks until a fresh OTP arrives — perfect for automated sign-up flows.@modelcontextprotocol/sdk + @hono/mcp for the remote agent interface.Go to Cloudflare Dashboard → Workers & Pages → D1 SQL Database → Create. Name it inbox-d1.
Copy the database_id for the next step. Tables are managed by the migrations/ directory in this repo — the deploy workflow applies D1 migrations automatically before deploying.
(Optional — only if you want to connect claude.ai as a remote MCP connector) also go to Storage & Databases → KV → Create a namespace, name it OAUTH_KV, and copy its namespace ID. Without it, OAuth is disabled and the MCP server works with API keys only.
In your forked repository, go to Settings → Secrets and variables → Actions and add:
- CLOUDFLARE_ACCOUNT_ID
- CLOUDFLARE_API_TOKEN
- TOML — use the comment-free template, fill in your D1 database_id and AI config (plus the OAUTH_KV namespace id if you created one), to avoid parse errors.
Then go to Actions → Deploy Auth Inbox to Cloudflare Workers → Run workflow.
After success, go to your Worker's Settings → Variables and Secrets and add a secret named JWT_SECRET (a long random string). Then open your Worker URL — since the users table is empty, the login page will prompt you to create the first admin account.
Delete the workflow logs afterwards to avoid leaking your config.
bash
git clone https://github.com/TooonyChen/AuthInbox.git
cd AuthInbox
pnpm install
bash
pnpm wrangler d1 create inbox-d1
Copy the database_id from the output.
(Optional — only for claude.ai remote connectors) also create the OAuth KV namespace:
bash
pnpm wrangler kv namespace create OAUTH_KV
Without it, OAuth is disabled and the MCP server works with API keys only.
bash
cp wrangler.toml.example wrangler.toml
Edit wrangler.toml and fill in at least:
```toml [vars] UseBark = "false"
# AI provider AI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta/openai" AI_API_KEY = "your-api-key" AI_API_FORMAT = "openai" AI_MODEL = "gemini-2.0-flash"
[[d1_databases]] binding = "DB" database_name = "inbox-d1" database_id = ""
# Optional — only for claude.ai remote connectors (OAuth): # [[kv_namespaces]] # binding = "OAUTH_KV" # must be named OAUTH_KV # id = "" ```
AI_API_FORMAT is one of:
| Value | Request path | Providers |
|---|---|---|
openai |
/v1/chat/completions |
OpenAI, Gemini (OpenAI-compat), DeepSeek, Groq, Mistral, … |
responses |
/v1/responses |
OpenAI Responses API |
anthropic |
/v1/messages |
Anthropic Claude direct |
Common AI_BASE_URL values:
OpenAI: https://api.openai.com
Gemini (OpenAI-compat): https://generativelanguage.googleapis.com/v1beta/openai
Anthropic: https://api.anthropic.com
DeepSeek: https://api.deepseek.com
Groq: https://api.groq.com/openai
Fallback provider (optional), used after the primary fails 3 retries:
toml
# AI_FALLBACK_BASE_URL = "https://api.openai.com"
# AI_FALLBACK_API_KEY = "fallback-api-key"
# AI_FALLBACK_API_FORMAT = "openai"
# AI_FALLBACK_MODEL = "gpt-4o-mini"
Optional Bark config: barkTokens, barkUrl.
Set the JWT secret (do not put it in wrangler.toml for production):
bash
pnpm exec wrangler secret put JWT_SECRET
bash
pnpm run deploy
This builds the frontend, applies remote D1 migrations, and deploys the Worker.
Output: https://auth-inbox.<your-subdomain>.workers.dev
Go to Cloudflare Dashboard → Websites → <your-domain> → Email → Email Routing → Routing Rules.
Catch-all address (forward all mail to the Worker):
Custom addresses (forward specific addresses):
Open your Worker URL. On first visit (empty users table) the login page turns into a "create admin account" form — create the first admin and you're in.
Two roles: admin and user.
A grant = (user, address pattern, allowed categories, allow-sensitive flag):
netflix@mail.example.com for exact match, *@mail.example.com for a whole domain.login_code / registration / password_reset / account_security / payment / other.password_reset and account_security are sensitive: even if listed in a grant, they are stripped unless the grant explicitly sets allow_sensitive. Fail-safe by design — a misclassified mail means a user sees one less mail, never one more.legacy and are always admin-only.So a user can be allowed to read the Netflix login code sent to a shared address, while the Netflix password reset mail on the same address stays admin-only. Everything is enforced in a single SQL-level query function shared by the web API and the MCP server.
Manage users and grants in the dashboard's Users & Access page (admin only).
Auth Inbox exposes a remote MCP server at https://<your-worker-domain>/mcp (Streamable HTTP). Two ways to authenticate:
Option A — OAuth (claude.ai remote connectors, and any OAuth-capable MCP client)
Requires the optional OAUTH_KV binding (see installation). Go to claude.ai → Settings → Connectors → Add custom connector and enter https://your.domain/mcp. Claude discovers the OAuth server automatically (dynamic client registration + PKCE), sends you to the Auth Inbox login/consent page, and connects as your account. Tokens inherit your role and grants; revoking a user in the dashboard kills their OAuth access immediately.
Option B — API key (Claude Code, Cursor, scripts, …)
aik_…, shown only once). Keys inherit your role and grants.bash
claude mcp add --transport http authinbox https://your.domain/mcp \
--header "Authorization: Bearer aik_xxx"
Available tools:
| Tool | Purpose |
|---|---|
list_addresses |
List inbox addresses the key's user may read |
list_codes |
List recent codes/links, filterable by address or service |
get_latest_code |
Get the single most recent code for an address/service |
wait_for_code |
Block (up to 55s) until a new code arrives — for automated sign-up/login flows |
All tools go through the same permission filter as the web API, so an agent holding a user's key or OAuth token can never read sensitive or raw content.
v2 is a breaking change:
FrontEndAdminID / FrontEndAdminPassword in wrangler.toml are no longer used — remove them. Accounts live in the D1 users table.JWT_SECRET secret: pnpm exec wrangler secret put JWT_SECRET.pnpm run db:migrate:remote (also runs automatically in pnpm run deploy and the GitHub Actions workflow). Existing data is preserved; old mails are marked category legacy (admin-only).POST /api/auth/setup — only works while the users table is empty).


/mcp (for claude.ai rembrowse all types & interfaces →
$ claude mcp add AuthInbox \
-- python -m otcore.mcp_server <graph>