Elaan MCP server
io.elaan/mcp·v0.1.3Create Elaan notification types, templates and brands, trigger sends, and debug delivery.
0 stars
Reviews
Write oneNobody has reviewed Elaan yet.
If you have run it, two minutes of your experience saves the next person an afternoon.
Elaan tools (26, 12 write)
write = sends, deletes, buys or postsRead from the package source without running it. The installed server may list more.
create_brandingwrite actionCreate a brand. `values` is an arbitrary key/value bag interpolated into templates, so one template can render for every customer you have \u2014 put whatever the templates reference here (product name, logo URL, colour, support address).
create_contactwrite actionCreate a contact. `attributes` are available to every template rendered for this recipient, so anything you would otherwise repeat in every trigger belongs here.
create_notification_typewrite actionCreate a notification type. The key is its permanent identity and is referenced by every template and preference, so choose it carefully \u2014 it cannot be renamed. Set allows_opt_out to false for transactional types (password resets, email verification) that a recipient must not be able to switch off; note that this removes only the recipient's veto, and channel_defaults still decides which chan
create_templatewrite actionCreate a template for one notification type on one channel. Content uses {{ slot }} placeholders filled at send time from the recipient's contact attributes, the resolved brand's values and the trigger's variables (most specific wins). A slot nobody filled renders empty rather than failing the send. Repeat blocks are supported for list data: {{#each lines}} ... {{ item.field }} ... {{/each}} \u201
delete_brandingwrite actionDelete a brand. The account default cannot be deleted and will return 409. Templates overriding this brand are not deleted, but sends naming it will fall back to the default.
delete_notification_typewrite actionSoft-delete a notification type. The row survives because templates and preferences reference it by key, and restore_notification_type brings it back. Templates of a deleted type can still be edited.
delete_templatewrite actionPermanently delete a template. This is a hard delete with no restore. Deleting the last template for a (type, channel) also removes that channel from the contact-facing preference matrix, because a channel with no template can never be delivered.
get_contactFetch one contact. Accepts either Elaan's internal id or your own identifier prefixed with 'ext:', e.g. 'ext:crm-12345'.
get_contact_preferencesThe per-type by per-channel matrix for one contact, with the effective on/off and whether they overrode the default. Only channels a type can actually reach (i.e. that have a template) are offered, and non-opt-out types are omitted entirely.
get_delivery_statsAggregate delivery counts for the account.
get_notification_eventThe outcome of one triggered event: pending, processed or failed, with per-channel errors. Channel failures are isolated, so a broken email template shows here without having blocked the inbox or push delivery of the same event. Start here when someone reports a notification did not arrive.
get_notification_typeFetch a single notification type by its key.
get_templateFetch one template by id.
list_brandingsList the account's brands. Every account has exactly one default brand, which cannot be deleted and is the fallback whenever a send names no brand or an unknown one.
list_contactsList or search contacts.
list_deliveriesThe delivery log, filterable by channel, status, recipient, notification type and time range. This is the tool for 'did this person get it, and if not why'.
list_notification_typesList every notification type in the account, with its per-channel defaults, declared variables and opt-out policy. Start here when you need to know what already exists.
list_templatesList every template on one channel, across all notification types, brands and languages.
list_templates_affected_byReport which email templates reference which of a notification type's declared variables. Advisory only \u2014 a template may legitimately use brand keys and contact attributes that are not declared variables \u2014 but it is the right check before changing or removing one.
preview_email_renderwrite actionRender an email template with sample variables and a chosen brand, without sending anything. Use this to check that slots resolve and that the brand-major fallback picked the template you expected.
restore_notification_typeUndo a soft delete, bringing the type and its configuration back.
set_contact_preferenceOverride one (type, channel) for one contact. Attempting this on a non-opt-out type returns 409.
trigger_notificationwrite actionSend a notification to 1-100 recipients. Returns 202 immediately with one event_id per recipient; delivery happens asynchronously, so use get_notification_event afterwards to see the outcome. An omitted or unknown branding_key falls back to the account default rather than failing. Variables may be flat strings or arrays of flat row objects for {{#each}} blocks. This sends real messages.
update_brandingwrite actionUpdate a brand's values and/or its email sender. Values are replaced wholesale, not merged \u2014 read the brand first if you mean to change one key.
update_notification_typewrite actionUpdate any combination of a type's channel defaults, declared variables and opt-out policy. Only the fields you pass are changed. Note that channel_defaults and variables are replaced wholesale, not merged.
update_templatewrite actionReplace a template's content. Same field rules as create_template. The notification type, brand and channel of an existing template cannot be changed \u2014 delete and recreate to move it.
Public scan report
scanner v0.1.9 · 2026-09-24 · same rubric, same numbers if you re-run it
- Code scan2 source files scanned25/25
- –Live reliabilityno gateway calls yet and no remote to proben/a
- –Tool poisoningtools not inspected (local package is not executed); not countedn/a
- Auth qualitystatic API keys via environment variables6/15
- Maintenancelast push 40 days ago12/15
- Maintainer identitynamespace and repository owner differ; GitHub account older than a year; website matches verified namespace7/10
How Elaan compares
Against every graded MCP server, from our own scans and uptime checks. Updated after each scan run.
- Safety score
- 77/100
- higher than 50% of 48,255 servers
- Tools
- 26
- the typical server has 7
- Tools that change things
- 46%
- typical: 0%. Fewer write tools means less an agent can break
What its tools let an agent do: 13 read · 4 create · 5 change · 3 delete · 1 run or deploy
Install Elaan in Claude Code, Cursor or VS Code
Runs npx -y @elaanio/mcp on your machine. Read the scan report first; the gateway never runs local packages.
claude mcp add mcp -- npx -y @elaanio/mcp
What the publisher says
From the Elaan repository's README, as published. We do not edit it. Read it on GitHub
Elaan JavaScript SDKs
Client SDKs for Elaan — drop-in notification inbox, preferences, and push-token management for your users' frontends.
This is the JavaScript/TypeScript family. Swift and Kotlin/Android live in their own repos (elaan-swift, elaan-kotlin).
Packages
How they fit together
@elaanio/core vanilla TS: client · stores · realtime transport
├─ @elaanio/react-core React provider + hooks (framework, no DOM)
│ ├─ @elaanio/react web components + fetch-SSE realtime
│ └─ @elaanio/react-native RN components (SSE via react-native-sse)
├─ @elaanio/vue Vue 3 components + composables
├─ @elaanio/svelte Svelte stores (headless)
└─ @elaanio/elements Web Components (works anywhere)The non-visual logic lives once in @elaanio/core; each framework package is a thin adapter over the core client + observable stores (React goes through the shared @elaanio/react-core hooks; Vue and Svelte bind the stores to their own reactivity). Adding another framework means a new binding over @elaanio/core, not a reimplementation of the client or stores.
Authentication (all packages)
The SDK never sees your API key. Your backend mints a short-lived contact token for the signed-in user (POST /v1/contacts/tokens with your service key, by external_id) and returns it to the client. You pass the SDK a tokenProvider callback that fetches a fresh token from your own endpoint; it refreshes automatically on expiry. See @elaanio/react for the full token flow.
Quick start — React (web)
import { ElaanProvider, NotificationBell, Preferences } from "@elaanio/react";
import "@elaanio/react/styles.css";
async function tokenProvider() {
const res = await fetch("/api/elaan-token"); // your endpoint
const { token, contact_id } = await res.json();
return { token, contactId: contact_id };
}
export function App() {
return (
<ElaanProvider apiBase="https://api.elaan.io/v1" tokenProvider={tokenProvider}>
<NotificationBell />
<Preferences />
</ElaanProvider>
);
}Quick start — React Native
Same provider and hooks; the components render with React Native primitives (View/FlatList/Switch/Modal) instead of DOM, and there's no stylesheet to import. Realtime works over SSE via react-native-sse (RN can't stream fetch, but its XHR-based EventSource can send the auth header), wired into the RN provider by default and falling back to polling when the deployment has realtime off. Pass realtime={null} for polling only.
Shortened. The full README is on GitHub.
Nothing above is checked by us. What we check is on the safety report.
Elaan: common questions
- Is Elaan MCP server safe?
- Mostly: it is graded B (77/100). Read the Elaan safety report
- How do I install Elaan?
- It runs on your machine. Copy the Claude Code, Cursor, VS Code or Claude Desktop config from the install section.
- Does Elaan need an API key?
- Yes. The registry entry asks for
ELAAN_API_KEY. - Is Elaan maintained?
- The last commit was 81 days ago (2026-08-15). The latest release is v0.1.3.
- How does Elaan compare with other MCP servers?
- safety score 77/100 (higher than 50% of 48,255 servers); tools 26 (the typical server has 7); tools that change things 46% (typical: 0%. Fewer write tools means less an agent can break). Full comparison.