Loading...
Loading...
Bi-weekly engineering deep dives on auth, notifications, and developer infrastructure. No spam.
Sign Up for UpdatesPublished by Zyphr
If your AI coding assistant can't actually do anything for your notification layer, it's just a fancy autocomplete. Today we're shipping @zyphr-dev/mcp-server — a Model Context Protocol server that turns Zyphr into a first-class tool your AI client can call directly.
Drop one config block into Claude Code, Cursor, Cline, Claude Desktop, or any other MCP-compatible client. Restart it. Now your AI can send emails, push notifications, SMS, and in-app messages. It can render templates with variables before sending. It can find and update subscribers. It can register webhooks and inspect delivery history. And — this is the part we're proudest of — it can integrate Zyphr into a brand-new project from scratch, writing the install commands and the actual code, without any docs spelunking.
{
"mcpServers": {
"zyphr": {
"command": "npx",
"args": ["-y", "@zyphr-dev/mcp-server"],
"env": {
"ZYPHR_API_KEY": "zy_test_..."
}
}
}
}
That's it. Same block works in every MCP-compatible client. Use a zy_test_* key while you're experimenting, swap to zy_live_* when you're ready to send for real.
You're starting a new Express service. You need transactional emails. So you:
express.json() ate your webhook body, debug for an hourIt works. It just takes the better part of an afternoon.
You open your editor. You say:
"Add Zyphr email to this Express app."
Your AI calls get_sdk_install_for_language and get_quickstart_for_channel back-to-back, drops two files into your project, and tells you to verify your sender domain and mount the router. Five minutes from "I want this" to working code.
"Now show me how to verify Zyphr webhooks in this Express app."
Same workflow. You get a verifier helper that uses HMAC-SHA256 with constant-time comparison, a route that mounts express.raw() before the JSON body parser (because raw bytes are mandatory for signature checks), and a 5-minute timestamp window that kills replay attacks. None of that is your AI guessing — it's the exact snippets we ship and test.
Eighteen tools across two layers.
get_sdk_install_for_language returns install commands and a minimal init snippet for Node, Python, Ruby, Go, PHP, or C#. Pass an optional packageManager to narrow npm → yarn, pip → poetry, etc.
get_quickstart_for_channel returns drop-in service files for the email, push, SMS, in-app, or webhook channel, in any of those six languages, with framework-tailored variants for Express, Next.js, Flask, FastAPI, Rails, Laravel, and ASP.NET Core. Webhook handlers always include signature verification — there is no opt-out, because there is no excuse for shipping an unverified webhook handler.
send_email, send_push, send_sms, send_inbox_messagelist_templates, get_template, render_template, create_templatefind_subscriber, list_subscribers, create_subscriber, update_subscriber, set_subscriber_preferenceslist_webhooks, create_webhook, get_webhook_deliveriesrender_template is the one we expect to be a sleeper hit. Hand it a template ID and a variable bag and it returns the rendered subject / HTML / text without sending anything — perfect for "show me what this would look like" loops before a send.
You'll get the most value from the MCP server if any of these apply:
npm init to a successful first send without leaving the editor.You should not install it if your AI client has no MCP support. (We don't list specific clients here because the list keeps growing — check your tool's docs for MCP.) For non-MCP clients, the REST API and SDKs are still the right path.
A few things we built in because letting an AI hit your production messaging API uninvited is a bad time.
ZYPHR_READ_ONLY=true suppresses every mutating tool. Sends, creates, updates — gone. You're left with the seven read tools (list_*, get_*, find_*, render_template, get_webhook_deliveries). Use this mode when you want the AI to investigate or report without touching state. It's also a great way to run a discovery session before you trust the AI with writes.
ZYPHR_ALLOWED_TOOLS="render_template,find_subscriber" is a comma-separated whitelist. When set, only the named tools are registered — everything else is invisible. Takes precedence over ZYPHR_READ_ONLY, so you can explicitly allow one mutating tool inside an otherwise read-only profile.
No delete_* tools. We don't ship them. If your AI needs to delete a subscriber or a template, do it from the dashboard. Destructive operations on a single command from a model loop is a footgun we'd rather not hand out.
zy_test_* keys always point at production, just like Stripe's test keys. There's no separate dev environment for end users to wire up. Test mode behaves the same as live mode for code paths but doesn't deliver to real recipients.
Errors from the Zyphr API are returned verbatim to your AI client, with full context — HTTP status code, error code, request ID, and any structured details the API provides. That means when your AI hits a 404 looking up a subscriber, it sees { status: 404, code: "not_found", ... } and tells you exactly that. When the API throws a 422 validation error on a malformed send, it sees { status: 422, code: "validation_error", details: { field: "to" } } and can correct itself on the spot.
We learned this the hard way during development — we initially returned just the error message and watched our AI client guess between three possible causes for a 404. With status codes restored, it just reads the response and moves on.
A few things on the roadmap:
check_account_readiness tool that aggregates "is your sender domain verified? do you have at least one template? are your push provider credentials configured?" into a single AI-readable checklist. The number-one cause of "why won't my email send" is missing setup, and we'd like to catch that before the first send_email call.If any of those would change your workflow, open an issue on the SDK repo and tell us.
npx -y @zyphr-dev/mcp-server with a zy_test_* key in the env block. Restart your MCP client. Ask it "what Zyphr tools do you have?" — you should see 18.
Then ask it to add Zyphr to a project, send you a welcome email, or render the welcome template with name='You' and show you what it would look like.
That's the moment we built this for.