About
Novu MCP Server
README
Novu MCP Server
Visit our main GitHub Repository »
✨ Features
A single MCP server that unlocks your entire Novu workspace for AI agents:
- Notifications — fetch and filter events with full execution logs and delivery status
- Subscribers — search and manage recipients by email, phone, name, or ID
- Workflows — list, inspect, create, update, and trigger notification workflows
- Preferences — read and update subscriber channel preferences (email, SMS, in-app, push, chat)
- Environments — view environments and their configuration
- Integrations — manage provider integrations across channels
- Auth & Identity —
whoamiverifies your credential (OAuth or API key) and reports the active region
🚀 Quick Start
You don't need to host anything — the server is fully managed. Pick the endpoint for your Novu Cloud region and point your MCP client at it:
| Region | Endpoint | Novu API |
|---|---|---|
| US | https://mcp.novu.co/ |
api.novu.co |
| EU | https://eu.mcp.novu.co/ |
eu.api.novu.co |
Each host is a dedicated deployment pinned to its region — there is no ?region=
query param anymore. (For backward compatibility, a ?region= that doesn't match
the host's region returns a 400 pointing you at the correct endpoint.)
Authentication
The server supports two ways to authenticate, and both work identically on either regional endpoint:
1. OAuth (recommended) — No API key to copy/paste. When your MCP client first
connects, the server responds with a 401 and an OAuth discovery document
(/.well-known/oauth-protected-resource) that points the client at Novu's
authorization server (Clerk). Your client opens the Novu sign-in + consent screen,
you pick an organization, and the client receives an access token automatically.
Any MCP client that supports remote OAuth (Cursor, Claude, ChatGPT, Windsurf, …) handles this flow for you — just add the server URL with no header.
Note: the client must request the
user:org:readscope (advertised in the discovery document) so the Novu API can resolve your organization. If your Novu account belongs to multiple organizations, you'll be asked to select one during consent.
2. API key — Provide your key from the Novu Dashboard as a bearer token:
Authorization: Bearer <your-novu-api-key>
When you present an API key, the server treats the session as API-key mode and will not trigger the OAuth sign-in flow — even on the hosted endpoints. The key is bound to a single environment (and thus region), so no extra configuration is needed; just connect to the endpoint for the region your account lives in.
Self-hosted Novu? OAuth is only available for Novu Cloud (US/EU) — the flow runs against Novu Cloud's authorization server, which a self-hosted deployment has no access to. Self-hosted deployments always authenticate with an API key. See Deploying your own instance and Local Development.
🎯 Environments
How requests map to a Novu environment depends on how you authenticate:
- API key — the key itself is bound to a single environment; requests always run against that environment.
- OAuth — the token is bound to your organization, and the Novu API defaults to the Development environment.
For OAuth sessions, every tool accepts an optional environmentId parameter to
target a specific environment (forwarded to the Novu API as the
Novu-Environment-Id header). Call get_environments first to list your
environments, then pass the _id of the one you want — for example, to inspect
Production notifications. The Novu API validates that the environment belongs
to your organization. With an API key the parameter is ignored — the key
already pins the environment.
Local / self-hosted API — to point this MCP server at a Novu API running
elsewhere (for example a self-hosted instance on http://localhost:3000), set
NOVU_API_URL in .dev.vars and run the server locally (see
Local Development). This replaces the old ?region=local
query param. Self-hosted always uses an API key — OAuth is Novu Cloud only.
🛠️ Usage
The server speaks the Streamable HTTP MCP transport at https://mcp.novu.co/
(US) and https://eu.mcp.novu.co/ (EU).
Cursor, Windsurf, Claude & other OAuth-capable clients
Any client that supports remote MCP servers with OAuth can connect with no header — the client runs the sign-in flow for you:
- URL (US):
https://mcp.novu.co/ - URL (EU):
https://eu.mcp.novu.co/
On first connection the client opens the Novu sign-in + consent screen. Approve it, select your organization, and the tools appear automatically.
API key (mcp-remote / stdio clients, self-hosted Novu)
For clients that only support stdio transports, if you prefer a static API key,
or if you run a self-hosted Novu instance (where OAuth is not available),
use the mcp-remote proxy with an
Authorization header. Presenting an API key keeps the client from launching the
OAuth flow:
{
"mcpServers": {
"novu": {
"command": "npx",
"args": [
"mcp-remote",
"https://mcp.novu.co/",
"--header",
"Authorization:Bearer your-novu-api-key"
]
}
}
}
For the EU region, swap the URL for https://eu.mcp.novu.co/.
📦 Available Tools
| Tool | Description |
|---|---|
whoami |
Show who is authenticated (verifies the credential against the Novu API) and the active region |
get_environments |
List all environments with their details and API keys |
get_notifications |
Fetch events with filtering by channel, template, subscriber, date, and more |
get_notification |
Get a specific notification with detailed execution logs |
find_subscribers |
Search subscribers by email, name, phone, or ID |
get_subscriber_preferences |
Get a subscriber's preferences across all channels and workflows |
update_subscriber_preferences |
Update a subscriber's channel preferences globally or per workflow |
get_workflows |
List all workflows with their basic information |
get_workflow |
Get a workflow's full definition, steps, and payload schema |
trigger_workflow |
Trigger a workflow for a subscriber with a custom payload |
get_integrations |
List configured provider integrations across channels |
💻 Local Development
Prerequisites: Node.js 20+ and pnpm.
# Clone and install
git clone https://github.com/novuhq/novu-mcp-server.git
cd novu-mcp-server
pnpm install
# Start the local worker
pnpm dev
The server runs at http://localhost:8787. Point your MCP client at it the same way you would the hosted version:
{
"mcpServers": {
"novu": {
"command": "npx",
"args": [
"mcp-remote",
"http://localhost:8787/",
"--header",
"Authorization:Bearer your-novu-api-key"
]
}
}
}
Configuration is read from .dev.vars (gitignored) — copy
.dev.vars.example to get started. The key variables are:
NOVU_API_URL— the Novu API this server proxies to (e.g.http://localhost:3000for a self-hosted API, orhttps://api.novu.co/https://eu.api.novu.cofor cloud).NOVU_REGION— the display label surfaced bywhoami.CLERK_OAUTH_ISSUER— the Clerk authorization server for OAuth. Leave empty to disable OAuth entirely and run API-key-only (the self-hosted mode).
For local development against a self-hosted Novu API on http://localhost:3000,
set NOVU_API_URL="http://localhost:3000" in .dev.vars and use your instance's
API key (OAuth is Novu Cloud only):
{
"mcpServers": {
"novu-local": {
"command": "npx",
"args": [
"mcp-remote",
"http://localhost:8787/",
"--header",
"Authorization:Bearer your-local-novu-api-key"
]
}
}
}
OAuth in local development
To exercise OAuth locally, set CLERK_OAUTH_ISSUER in .dev.vars to a Clerk
authorization server your Novu API trusts (e.g. https://clerk.dashboard.novu.co
for US). The MCP endpoint origin is derived from the request URL, so run the dev
server and point your MCP client at the same URL (e.g. http://localhost:8787/).
RFC 9728 requires the PRM resource field to exactly match the MCP endpoint URL;
connecting via a different host/port than the server is bound to causes clients
like Cursor to discard the metadata and register without the user:org:read scope.
When CLERK_OAUTH_ISSUER is empty, the OAuth discovery endpoints return 404 and
401 responses omit the OAuth metadata, so clients fall back to API-key auth.
Deploying your own instance
The server is a standard Cloudflare Worker. wrangler.jsonc is organized so the
top-level config is local-dev-only (no routes, so wrangler dev serves on
localhost and OAuth discovery advertises the localhost origin), while real
deployments live under named environments:
pnpm deploy→--env us(bindsmcp.novu.co,NOVU_API_URL=https://api.novu.co)pnpm deploy:eu→--env eu(bindseu.mcp.novu.co,NOVU_API_URL=https://eu.api.novu.co)
To deploy your own instance, fork the repo and add an environment under env
(or edit an existing one) with your own routes, NOVU_API_URL, and
NOVU_REGION, then deploy it with wrangler deploy --env <name>. A self-deployed
instance works out of the box with API-key authentication against whatever
NOVU_API_URL points at — including a self-hosted Novu API. OAuth on your own
deployment requires setting the CLERK_OAUTH_ISSUER secret
(wrangler secret put CLERK_OAUTH_ISSUER --env <name>) to an authorization
server that your Novu API trusts; leave it unset for API-key-only.
Scripts
pnpm dev— Run the worker locally via Wrangler (top-level, route-free config)pnpm deploy— Deploy the US worker (mcp.novu.co,--env us)pnpm deploy:eu— Deploy the EU worker (eu.mcp.novu.co,--env eu)pnpm type-check— Run TypeScript type checkingpnpm lint:fix— Fix linter issues with Biomepnpm format— Format the codebase with Biome
Project structure
src/
├── index.ts # Worker entry — auth extraction and routing
├── oauth.ts # OAuth discovery, 401 bootstrap, initialize-time probe
├── server/NovuMCP.ts # Durable Object hosting the MCP agent
├── tools/ # One file per tool group (workflows, subscribers, …)
├── utils/ # API client, validation, tool factory
└── types/ # Shared TypeScript types
Add new tools by creating a register*Tools function under src/tools/ and wiring it in src/server/NovuMCP.ts.
🔒 Security
- The server is a pure OAuth pass-through: it does not mint, exchange, or
re-sign tokens. It never validates tokens itself — it advertises Novu's Clerk
authorization server and forwards the caller's
Authorizationheader verbatim to the Novu API, which validates it and resolves the org/permissions. - OAuth access tokens (Clerk opaque
oat_…tokens) are short-lived and revocable from the Novu side, so they are far safer than a long-lived API key. - Whether OAuth token or legacy API key, the credential is scoped to your MCP session: it is handed to the session's Durable Object via the runtime's props channel — never placed in URLs, where it would leak into request logs — and is discarded with the session. The server holds no ambient credentials.
- Never commit API keys or issuer config. Use
.dev.varsfor local values (already gitignored). - Treat your Novu API key like a password — rotate it from the dashboard if you suspect it has been exposed.
🤝 Contributing
Make Changes
git checkout -b feat/your-change pnpm dev # Test locally pnpm type-check # Verify types git commit -m "feat: your change" git push origin feat/your-changeOpen a Pull Request
- Use a descriptive title with
feat:,fix:,docs:, orchore:prefix - Include a short description of the change and, where relevant, a sample tool call
- Use a descriptive title with
Guidelines:
- Keep tool descriptions concise — they are surfaced verbatim to LLMs
- Validate inputs with Zod schemas in
src/utils/ - Prefer the
ToolFactoryhelpers for standard CRUD endpoints - Something missing? Open a GitHub issue
Need help? Email us at [email protected] or join the Discord.
Thank you for contributing! 🙏
Installing Novu
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/novuhq/novu-mcp-serverFAQ
Is Novu MCP free?
Yes, Novu MCP is free — one-click install via Unyly at no cost.
Does Novu need an API key?
No, Novu runs without API keys or environment variables.
Is Novu hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Novu in Claude Desktop, Claude Code or Cursor?
Open Novu on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
Fetch
Web content fetching and conversion for efficient LLM usage.
AWS KB Retrieval
Retrieval from AWS Knowledge Base using Bedrock Agent Runtime.
by modelcontextprotocolSpring AI MCP Server
Provides auto-configuration for setting up an MCP server in Spring Boot applications.
llm-analysis-assistant
A very streamlined mcp client that supports calling and monitoring stdio/sse/streamableHttp, and can also view request responses through the /logs page. It also
by xuzexin-hzCompare Novu with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All ai MCPs
