Courier
REMOTE · MCP.COURIER.COM · SCANNED SEP 24
Send notifications, manage templates, and configure integrations with Courier.
Available components
How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →
Endpoint Security63
- The endpoint's TLS certificate is valid, in date, and uses a strong key. View diagnostics → Pass
- Authorisation check failed: no authorisation is required to call this server, and it exposes a tool marked destructive (replace_journey). See how to fix → View diagnostics → Fail
- HTTPS is enforced; there's no plaintext access path. View diagnostics → Pass
- The HSTS (Strict-Transport-Security) header is present. View diagnostics → Pass
- DNSSEC check failed: this domain isn't protected by DNSSEC. See how to fix → View diagnostics → Fail
Transport & Reachability100
- Verified streamable-http transport via a live MCP handshake. View diagnostics → Pass
Schema Quality & AI Usability82
- AI-judged instruction clarity (excellent).Pass
- Tool/resource definitions use about 14709 tokens (~91/item across 161 items; 161 tools + 0 resources), lean.Pass
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management100
- Stability check failed: schema churn in the 30 days we've observed: 0 tool removals, 1 breaking changes, 0 auth/transport breaks, 17 additions. See how to fix → Fail
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 99% of tool parameters carry a description.Partial
Tool Safety50
- Injection-marker check failed: the description of tool "get_notification_metrics" contains an instruction to conceal the call from the user, the text "do NOT tell the user", at byte 3262 of that field. See how to fix → Fail
- All 25 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
- An AI judge read all 161 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
How do I install the Courier MCP server?
Courier is a hosted endpoint at https://mcp.courier.com/, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
remote · mcp.courier.com
claude mcp add --transport http trycourier-courier 'https://mcp.courier.com/'
{
"mcpServers": {
"trycourier-courier": {
"url": "https://mcp.courier.com/"
}
}
} {
"servers": {
"trycourier-courier": {
"type": "http",
"url": "https://mcp.courier.com/"
}
}
} [mcp_servers.trycourier-courier] url = "https://mcp.courier.com/"
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"trycourier-courier": {
"type": "remote",
"url": "https://mcp.courier.com/",
"enabled": true
}
}
} openclaw mcp add trycourier-courier --url 'https://mcp.courier.com/' --transport streamable-http
mcp_servers:
trycourier-courier:
url: "https://mcp.courier.com/" {
"McpServers": {
"trycourier-courier": {
"Transport": "http",
"Url": "https://mcp.courier.com/"
}
}
} assistant mcp add trycourier-courier -t streamable-http -u 'https://mcp.courier.com/'
{
"mcpServers": {
"trycourier-courier": {
"type": "http",
"url": "https://mcp.courier.com/"
}
}
} The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 23 Sept 26 0
- New tool “cancel_broadcast_schedule”, which the server declares destructive security
- New tool “delete_broadcast”, which the server declares destructive security
- Tool “put_journey_template_locale” rewrote its description, which is the text the model reads security
- Tool “replace_preference_topic” rewrote its description, which is the text the model reads security
- Schema quality: 13327 → 14709 ▼ functional
- New tool “create_broadcast” functional
- New tool “duplicate_broadcast” functional
- New tool “get_broadcast” functional
- New tool “get_broadcast_content” functional
- New tool “get_journey_run” functional
- New tool “list_broadcasts” functional
- New tool “list_journey_run_steps” functional
- New tool “list_journey_runs” functional
- New tool “put_broadcast_content” functional
- New tool “release_user_digest” functional
- New tool “rename_broadcast” functional
- New tool “schedule_broadcast” functional
- New tool “send_broadcast” functional
- New tool “trace_message” functional
- “create_preference_topic” added an optional parameter “digest” cosmetic
- “replace_preference_topic” added an optional parameter “digest” cosmetic
- “update_user_preference_topic” added an optional parameter “digest_schedule_id” cosmetic
- “update_user_preference_topic” added an optional parameter “tenant_id” cosmetic
- “put_journey_template_locale” reworded the description of “journey_id” cosmetic
- “put_journey_template_locale” reworded the description of “notification_id” cosmetic
- “put_journey_template_locale” reworded the description of “state” cosmetic
- 16 Sept 26 0
- Tool “create_journey_template” rewrote its description, which is the text the model reads security
- Tool “create_notification” rewrote its description, which is the text the model reads security
- Tool “put_notification_content” rewrote its description, which is the text the model reads security
- Tool “put_notification_element” rewrote its description, which is the text the model reads security
- Tool “put_notification_locale” rewrote its description, which is the text the model reads security
- Tool “replace_notification” rewrote its description, which is the text the model reads security
- “create_journey_template” reworded the description of “journey_id” cosmetic
- “create_notification” reworded the description of “state” cosmetic
- “get_journey” reworded the description of “journey_id” cosmetic
- “get_journey_template” reworded the description of “journey_id” cosmetic
- “get_journey_template” reworded the description of “notification_id” cosmetic
- “get_journey_template_content” reworded the description of “journey_id” cosmetic
- “get_journey_template_content” reworded the description of “notification_id” cosmetic
- “get_notification” reworded the description of “notification_id” cosmetic
- “get_notification” reworded the description of “version” cosmetic
- “get_notification_content” reworded the description of “notification_id” cosmetic
- “get_notification_draft_content” reworded the description of “notification_id” cosmetic
- “get_user_preferences” reworded the description of “tenant_id” cosmetic
- “list_journey_templates” reworded the description of “cursor” cosmetic
- “list_journey_templates” reworded the description of “journey_id” cosmetic
- “list_journeys” reworded the description of “cursor” cosmetic
- “list_journeys” reworded the description of “version” cosmetic
- “list_messages” reworded the description of “archived” cosmetic
- “list_messages” reworded the description of “cursor” cosmetic
- “list_notifications” reworded the description of “cursor” cosmetic
- “list_providers” reworded the description of “cursor” cosmetic
- “put_journey_template_content” reworded the description of “elements” cosmetic
- “put_journey_template_content” reworded the description of “journey_id” cosmetic
- “put_journey_template_content” reworded the description of “notification_id” cosmetic
- “put_notification_content” reworded the description of “notification_id” cosmetic
- “put_notification_content” reworded the description of “state” cosmetic
- “put_notification_content” reworded the description of “version” cosmetic
- “put_notification_element” reworded the description of “element_id” cosmetic
- “put_notification_element” reworded the description of “notification_id” cosmetic
- “put_notification_element” reworded the description of “state” cosmetic
- “put_notification_locale” reworded the description of “notification_id” cosmetic
- “put_notification_locale” reworded the description of “state” cosmetic
- “replace_journey” reworded the description of “journey_id” cosmetic
- “replace_notification” reworded the description of “notification_id” cosmetic
- “replace_notification” reworded the description of “state” cosmetic
- 15 Sept 26 −3
- Injection markers: pass → fail ▼ security
- New tool “get_notification_metrics” functional
- 4 Sept 26 +1
- Stability: pass → fail ▼ security
- A breaking change shipped without a version bump: still 1.3.7 ▼ security
- Tool “create_journey” rewrote its description, which is the text the model reads security
- Tool “create_journey_template” rewrote its description, which is the text the model reads security
- Tool “create_notification” rewrote its description, which is the text the model reads security
- Tool “invoke_automation_template” rewrote its description, which is the text the model reads security
- Tool “invoke_journey” rewrote its description, which is the text the model reads security
- Tool “list_automations” rewrote its description, which is the text the model reads security
- Tool “list_journeys” rewrote its description, which is the text the model reads security
- Tool “replace_journey” rewrote its description, which is the text the model reads security
- Tool “send_message” rewrote its description, which is the text the model reads security
- Tool “send_message_template” rewrote its description, which is the text the model reads security
- Tool “send_message_to_list” rewrote its description, which is the text the model reads security
- Tool “update_translation” rewrote its description, which is the text the model reads security
- Tool “bulk_subscribe_to_list” is now declared destructive security
- Tool “update_provider” is now declared destructive security
- “replace_tenant_template” made “content” required, so existing callers break ▼ functional
- Destructive annotations: All 23 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation. functional
- “create_or_update_tenant” reworded the description of “default_preferences” cosmetic
- “replace_journey” reworded the description of “nodes” cosmetic
- “replace_tenant_template” reworded the description of “channels” cosmetic
- “replace_tenant_template” reworded the description of “content” cosmetic
- “replace_tenant_template” reworded the description of “providers” cosmetic
- “replace_tenant_template” reworded the description of “routing” cosmetic
- “update_audience” reworded the description of “filter” cosmetic
- 26 Aug 26 81
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
- 25 Aug 26 0
- Stability: 0.97 → pass security
- 20 Aug 26 0
- Tool “create_journey” rewrote its description, which is the text the model reads security
- Tool “create_journey_template” rewrote its description, which is the text the model reads security
- Tool “put_journey_template_content” rewrote its description, which is the text the model reads security
- Tool “replace_journey” rewrote its description, which is the text the model reads security
- Tool “put_journey_template_content” is now declared destructive security
- Tool “replace_journey” is now declared destructive security
- “create_journey” reworded the description of “state” cosmetic
- “create_journey_template” reworded the description of “state” cosmetic
- “put_journey_template_content” reworded the description of “state” cosmetic
- “replace_journey” reworded the description of “state” cosmetic
- 11 Aug 26 0
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 24 Sept 2026 · Probed https://mcp.courier.com
TLS valid
Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .
| Subject | Issuer | Valid from | Valid until | Key | Signature | Serial |
|---|---|---|---|---|---|---|
| CN=mcp.courier.com | CN=WE1,O=Google Trust Services,C=US | 9 Aug 2026 | 7 Nov 2026 | ECDSA 256 | ECDSA-SHA256 | df2aea7fc821556213cbc21276951523 |
| SANs: mcp.courier.com | ||||||
| CN=WE1,O=Google Trust Services,C=US (CA) | CN=GTS Root R4,O=Google Trust Services LLC,C=US | 13 Dec 2023 | 20 Feb 2029 | ECDSA 256 | ECDSA-SHA384 | 7ff31977972c224a76155d13b6d685e3 |
| CN=GTS Root R4,O=Google Trust Services LLC,C=US (CA) | CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE | 15 Nov 2023 | 28 Jan 2028 | ECDSA 384 | SHA256-RSA | 7fe530bf331343bedd821610493d8a1b |
Background: What to check on a remote MCP endpoint →
DNSSEC insecure
Validation of mcp.courier.com. — Not signed
| Zone | DS | Keys | Algorithms | Outcome |
|---|---|---|---|---|
| . | trust_anchor | 20326, 38696 | 8, 8 | Verified |
| com. | present | 19718 | 13 | Verified |
| courier.com. | absent | Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation |
Authentication No authorisation required
The endpoint answered without asking for a token. Anyone who knows the URL can reach it.
| Result | No authorisation required |
|---|---|
| HTTP status | 200 |
| Header | Value |
|---|---|
| strict-transport-security | max-age=15552000; includeSubDomains |
| content-security-policy | default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests |
| x-content-type-options | nosniff |
| x-frame-options | SAMEORIGIN |
| referrer-policy | no-referrer |
Background: How OAuth 2.1 works in the 2026 MCP spec →
Transports 2 probes
| Transport | URL | Outcome | Status | Location |
|---|---|---|---|---|
| streamable-http | https://mcp.courier.com | Verified | 200 | |
| http (plaintext) | http://mcp.courier.com | HTTPS enforced | 301 | https://mcp.courier.com/ |
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
add_bulk_users ~42
Add users to an existing bulk job.
| Name | Type | Req | Description |
|---|---|---|---|
| job_id | string | yes | The bulk job ID |
| users | array | yes | Array of user objects to add |
No output schema declared.
No examples provided.
add_subscribers_to_list ~46
Append subscribers to a list without removing existing subscribers.
| Name | Type | Req | Description |
|---|---|---|---|
| list_id | string | yes | The list ID |
| recipients | array | yes | Recipients to set on the list |
No output schema declared.
No examples provided.
add_user_to_tenant ~52
Add a user to a tenant.
| Name | Type | Req | Description |
|---|---|---|---|
| profile | object | – | Tenant-scoped profile overrides |
| tenant_id | string | yes | The tenant ID |
| user_id | string | yes | The user ID |
No output schema declared.
No examples provided.
archive_journey ~39
Archive a journey. Archived journeys cannot be invoked but existing runs continue to completion.
| Name | Type | Req | Description |
|---|---|---|---|
| journey_id | string | yes | The journey template ID to archive |
No output schema declared.
No examples provided.
archive_journey_template ~52
Archive a journey-scoped notification template. Archived templates cannot be sent.
| Name | Type | Req | Description |
|---|---|---|---|
| journey_id | string | yes | The journey template ID that owns this notification |
| notification_id | string | yes | The notification template ID |
No output schema declared.
No examples provided.
archive_notification ~29
Archive a notification template by ID.
| Name | Type | Req | Description |
|---|---|---|---|
| notification_id | string | yes | The notification template ID to archive |
No output schema declared.
No examples provided.
archive_preference_section ~49
Archive a preference section. The section must be empty: delete its topics first, otherwise the request fails with 409.
| Name | Type | Req | Description |
|---|---|---|---|
| section_id | string | yes | Id of the preference section to archive |
No output schema declared.
No examples provided.
archive_preference_topic ~46
Archive a topic within a section.
| Name | Type | Req | Description |
|---|---|---|---|
| section_id | string | yes | Id of the preference section |
| topic_id | string | yes | Id of the subscription preference topic to archive |
No output schema declared.
No examples provided.
archive_request ~39
Archive a send request and all its associated messages by request ID.
| Name | Type | Req | Description |
|---|---|---|---|
| request_id | string | yes | The request ID (requestId returned from /send) |
No output schema declared.
No examples provided.
archive_routing_strategy ~46
Archive a routing strategy. The strategy must not have associated notification templates; unlink all templates before archiving.
| Name | Type | Req | Description |
|---|---|---|---|
| routing_strategy_id | string | yes | The routing strategy ID to archive |
No output schema declared.
No examples provided.
bulk_add_user_tenants ~51
Add a user to multiple tenants at once. A custom profile can be supplied per tenant.
| Name | Type | Req | Description |
|---|---|---|---|
| tenants | array | yes | Array of tenant associations |
| user_id | string | yes | The user ID |
No output schema declared.
No examples provided.
bulk_add_user_tokens ~51
Add multiple push/device tokens for a user in one request. Overwrites matching existing tokens.
| Name | Type | Req | Description |
|---|---|---|---|
| tokens | array | yes | Token records to upsert |
| user_id | string | yes | The user ID |
No output schema declared.
No examples provided.
bulk_replace_user_preferences ~122
Replace a user's complete set of preference overrides in one request. The topics in the body become the recipient's entire override set: listed topics are created or updated, and every existing override not included is reset to its topic default. An empty `topics` array clears all overrides. Validation-atomic (all-or-nothing).
| Name | Type | Req | Description |
|---|---|---|---|
| tenant_id | string | – | Scope the replacement to a specific tenant context |
| topics | array | yes | The complete set of topic overrides. An empty array resets every existing override. |
| user_id | string | yes | The user ID |
No output schema declared.
No examples provided.
bulk_subscribe_to_list ~47
Replace all subscribers on a list with the given recipients.
| Name | Type | Req | Description |
|---|---|---|---|
| list_id | string | yes | The list ID |
| recipients | array | yes | Recipients to set on the list |
No output schema declared.
No examples provided.
bulk_update_user_preferences ~108
Additively create or update a user's preferences for one or more topics in a single request. Only the topics in the body are touched; existing overrides for other topics are left untouched. Partial-success: valid topics are written and returned in `items`, unapplicable ones collected in `errors`.
| Name | Type | Req | Description |
|---|---|---|---|
| tenant_id | string | – | Scope the update to a specific tenant context |
| topics | array | yes | Topics to create or update |
| user_id | string | yes | The user ID |
No output schema declared.
No examples provided.
cancel_automation ~85
Cancel a running automation by its cancelation_token. This invokes a second ad-hoc automation with a single cancel step. The token must match the cancelation_token set when the original automation was started. Note: spelling is "cancelation_token" (single "l").
| Name | Type | Req | Description |
|---|---|---|---|
| cancelation_token | string | yes | The cancelation_token that was set when the automation was originally invoked |
No output schema declared.
No examples provided.
cancel_broadcast_schedule ~34
Cancel a broadcast's scheduled send. The broadcast itself is kept.
| Name | Type | Req | Description |
|---|---|---|---|
| broadcast_id | string | yes | The broadcast id |
No output schema declared.
No examples provided.
cancel_journey ~110
Cancel journey runs. Supply EXACTLY ONE of cancelation_token (cancels every run associated with the token) or run_id (cancels a single run). Cancelation is idempotent: a run that already finished or was already canceled is left unchanged.
| Name | Type | Req | Description |
|---|---|---|---|
| cancelation_token | string | – | Cancels every run associated with this token. Mutually exclusive with run_id. |
| run_id | string | – | Cancels a single run by id. Mutually exclusive with cancelation_token. |
No output schema declared.
No examples provided.
cancel_message ~38
Cancel a message that is currently being delivered. Returns the message details with updated status.
| Name | Type | Req | Description |
|---|---|---|---|
| message_id | string | yes | The message ID to cancel |
No output schema declared.
No examples provided.
cancel_notification_submission ~40
Cancel a notification template submission.
| Name | Type | Req | Description |
|---|---|---|---|
| notification_id | string | yes | The notification template ID |
| submission_id | string | yes | The submission ID to cancel |
No output schema declared.
No examples provided.
courier_installation_guide ~85
Get the Courier SDK installation guide for a specific platform. For client-side SDKs (React, iOS, Android, Flutter, React Native), also generates a sample JWT.
| Name | Type | Req | Description |
|---|---|---|---|
| platform | string | yes | The platform to get installation guide for |
| user_id | string | – | User ID for JWT generation (client-side SDKs only). Defaults to "example_user". |
No output schema declared.
No examples provided.
create_brand ~152
Create a new brand. The API requires settings — omitting it returns a 400. If you do not have specific brand colors, omit settings and a safe default will be used automatically (black primary, white secondary). Example: { name: "Acme", settings: { colors: { primary: "#1a73e8", secondary: "#ffffff" } } }.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | – | Optional brand ID; auto-generated if omitted |
| name | string | yes | Brand display name |
| settings | object | – | Brand appearance settings. If omitted, defaults to { colors: { primary: "#000000", secondary: "#ffffff" } }. |
| snippets | object | – | Brand snippets |
No output schema declared.
No examples provided.
create_broadcast ~77
Create a broadcast: a one-off message to a list or audience on a single channel. It starts as a draft with no content; add content with put_broadcast_content, then send_broadcast or schedule_broadcast.
| Name | Type | Req | Description |
|---|---|---|---|
| channel | string | yes | The single delivery channel for this broadcast |
| name | string | yes | Human-readable name |
No output schema declared.
No examples provided.
create_bulk_job ~50
Create a new bulk job for sending messages to multiple recipients. Workflow: create_bulk_job → add_bulk_users → run_bulk_job.
| Name | Type | Req | Description |
|---|---|---|---|
| message | object | yes | Bulk message definition with event/template and content |
No output schema declared.
No examples provided.
create_journey ~447
Create a new journey. Always created as a draft; making it live is a separate step this tool cannot perform. Send two nodes: the trigger, and an exit node last. Both are required — a create with no exit node is rejected, and the API reports that as "exit node must be the last node in the journey" even when no exit was sent at all. Send and delay nodes are added afterwards by replace_journey, once journey-scoped templates exist. Node ids are server-generated; do NOT include an id field. Example: { name: "Welcome Journey", nodes: [{ type: "trigger", trigger_type: "api-invoke" }, { type: "exit" }], enabled: true }. The result carries a "verification" object read back from the server after the write — check it every time. verified:true means what you asked for is what saved. verified:false names what did not: "fieldMismatches" for node fields that failed to land, "nodeCountMismatch" for a node dropped or added, and "unknownTemplateReferences" for a send node pointing at a template id this journey does not have — almost always a mistyped id, so re-copy it from the create_journey_template or get_journey response it came from. Fix the specific thing named and send the corrected document. Re-sending an identical call changes nothing, and every replace_journey overwrites the whole draft again. An "errorKind" of "unauthorized" means the write itself succeeded and only the read-back was refused: report that as unconfirmed, never as a failed write.
| Name | Type | Req | Description |
|---|---|---|---|
| enabled | boolean | – | Whether the journey is active. Defaults to true. |
| name | string | yes | Journey display name |
| nodes | array | yes | The trigger node, then a terminal exit node — both required. Send and delay nodes are added later by replace_journey. Node ids are server-generated — do NOT include an id field. Example: [{ type: "tr… |
| state | string | – | Must be "DRAFT". These tools cannot publish. |
No output schema declared.
No examples provided.
create_journey_template ~335
Create a notification template scoped to a journey. Always created as a draft; making it live is a separate step this tool cannot perform. The template can then be referenced in journey send nodes. content.elements must be wrapped in a channel block — the API rejects bare elements. Example: { journey_id: "j-abc", channel: "email", notification: { name: "Welcome Email", tags: [], brand: null, subscription: null, content: { version: "2022-01-01", elements: [{ type: "channel", channel: "email", elements: [{ type: "text", content: "Hello!" }] }] } } }. The result carries a "verification" object confirming the new id is really present on the journey. verified:true means the id in this response is safe to reference from a send node. verified:false means it is not visible yet — re-read the journey before referencing it, and do not create a second template to work around it. An "errorKind" of "unauthorized" means the template was created and only the check was refused.
| Name | Type | Req | Description |
|---|---|---|---|
| channel | string | yes | Channel for this template (e.g. "email", "push", "sms", "inbox") |
| journey_id | string | yes | The journey template ID. Copy it exactly, character for character, from the response that returned it — never retype it from memory or reconstruct it. |
| notification | object | yes | Notification template definition |
| provider_key | string | – | Specific provider key to target |
| state | string | – | Must be "DRAFT". These tools cannot publish. |
No output schema declared.
No examples provided.
create_list ~40
Create or update a list by list ID.
| Name | Type | Req | Description |
|---|---|---|---|
| list_id | string | yes | The list ID |
| name | string | yes | Display name for the list |
No output schema declared.
No examples provided.
create_notification ~148
Create a V2 notification template. name is required. Content may be provided inline or set separately afterwards. A newly created template is a draft; making it live is a separate step this tool cannot perform. Link a routing strategy via notification.routing.strategy_id to control which channels are used. Example: { notification: { name: 'welcome-email', tags: [], brand: null, subscription: null, routing: { strategy_id: 'rs_01abc' }, content: { version: '2022-01-01', elements: [] } } }.
| Name | Type | Req | Description |
|---|---|---|---|
| notification | object | yes | Notification template payload |
| state | string | – | Must be "DRAFT". These tools cannot publish. |
No output schema declared.
No examples provided.
create_or_merge_user ~71
Create a new user profile or merge supplied values into an existing profile (POST). Existing fields not included are preserved.
| Name | Type | Req | Description |
|---|---|---|---|
| profile | object | – | Profile data to create or merge (e.g. { email: "...", phone_number: "..." }) |
| user_id | string | yes | The user ID |
No output schema declared.
No examples provided.
create_or_replace_user_push_token ~63
Create or replace a push/device token for a user.
| Name | Type | Req | Description |
|---|---|---|---|
| device | object | – | Device metadata |
| provider_key | string | yes | Push provider |
| token | string | yes | The token string |
| user_id | string | yes | The user ID |
No output schema declared.
No examples provided.
create_or_update_tenant ~159
Create or replace a tenant. Tenants represent organizations or groups that users belong to.
| Name | Type | Req | Description |
|---|---|---|---|
| brand_id | string | – | Brand ID to associate with this tenant |
| default_preferences | object | – | Default notification preferences applied to users in this tenant. Example: { "items": [{ "id": "topic_abc", "status": "OPTED_IN", "type": "subscription_topic" }] } |
| name | string | yes | Display name for the tenant |
| parent_tenant_id | string | – | Parent tenant ID for hierarchical tenants |
| properties | object | – | Custom properties for the tenant |
| tenant_id | string | yes | The tenant ID |
| user_profile | object | – | Default profile data for users in this tenant |
No output schema declared.
No examples provided.
create_preference_section ~86
Create a preference section in your workspace. The section id is generated and returned. Add topics afterwards with create_preference_topic.
| Name | Type | Req | Description |
|---|---|---|---|
| has_custom_routing | boolean | – | Whether the section defines custom routing for its topics |
| name | string | yes | Human-readable name for the section |
| routing_options | array | – | Default channels for the section. Defaults to empty if omitted. |
No output schema declared.
No examples provided.
create_preference_topic ~196
Create a subscription preference topic inside a section. The topic id is generated and returned. Fails with 404 if the section does not exist.
| Name | Type | Req | Description |
|---|---|---|---|
| allowed_preferences | array | – | Preference controls a recipient may customize for this topic |
| default_status | string | yes | Default subscription status applied when a recipient has not set their own |
| digest | – | – | Batch this topic's notifications into a scheduled digest. Omit to leave any existing digest untouched; pass null to turn it off. |
| include_unsubscribe_header | boolean | – | Whether to include a list-unsubscribe header on emails for this topic |
| name | string | yes | Human-readable name for the preference topic |
| routing_options | array | – | Default channels delivered for this topic. Defaults to empty if omitted. |
| section_id | string | yes | Id of the preference section to create the topic in |
| topic_data | object | – | Arbitrary metadata associated with the topic |
No output schema declared.
No examples provided.
create_provider ~127
Create a new provider (integration) configuration. Once routing strategies or notification templates reference this config, credential or settings mistakes can affect live sends—confirm provider key and settings against list_provider_catalog before saving. The provider field must be a known Courier provider key.
| Name | Type | Req | Description |
|---|---|---|---|
| alias | string | – | Short alias for referencing this provider |
| provider | string | yes | Provider key from the catalog (e.g. sendgrid, twilio, firebase-fcm) |
| settings | object | – | Provider-specific settings (API keys, credentials, etc.) |
| title | string | – | Display name for this provider configuration |
No output schema declared.
No examples provided.
create_routing_strategy ~98
Create a routing strategy defining how notifications are delivered across channels and providers.
| Name | Type | Req | Description |
|---|---|---|---|
| channels | object | – | Per-channel delivery configuration |
| description | string | – | Description of the routing strategy |
| name | string | yes | Human-readable name for the routing strategy |
| providers | object | – | Per-provider delivery configuration |
| routing | object | yes | Routing tree defining channel selection method and order |
| tags | array | – | Tags for categorization |
No output schema declared.
No examples provided.
delete_audience ~29
Delete an audience by its ID.
| Name | Type | Req | Description |
|---|---|---|---|
| audience_id | string | yes | The audience ID to delete |
No output schema declared.
No examples provided.
delete_brand ~28
Delete a brand by its ID.
| Name | Type | Req | Description |
|---|---|---|---|
| brand_id | string | yes | The brand ID to delete |
No output schema declared.
No examples provided.
delete_broadcast ~24
Delete a broadcast.
| Name | Type | Req | Description |
|---|---|---|---|
| broadcast_id | string | yes | The broadcast id |
No output schema declared.
No examples provided.
delete_list ~26
Delete a list by its ID.
| Name | Type | Req | Description |
|---|---|---|---|
| list_id | string | yes | The list ID |
No output schema declared.
No examples provided.
delete_profile ~27
Delete a user profile permanently.
| Name | Type | Req | Description |
|---|---|---|---|
| user_id | string | yes | The user ID to delete |
No output schema declared.
No examples provided.
delete_provider ~41
Delete a provider configuration. Returns 409 if the provider is still referenced by routing or notifications.
| Name | Type | Req | Description |
|---|---|---|---|
| provider_id | string | yes | The provider configuration ID to delete |
No output schema declared.
No examples provided.
delete_tenant ~29
Delete a tenant by its ID.
| Name | Type | Req | Description |
|---|---|---|---|
| tenant_id | string | yes | The tenant ID to delete |
No output schema declared.
No examples provided.
delete_tenant_preference ~45
Remove default notification preference for a topic from a tenant.
| Name | Type | Req | Description |
|---|---|---|---|
| tenant_id | string | yes | The tenant ID |
| topic_id | string | yes | The subscription topic ID |
No output schema declared.
No examples provided.
delete_tenant_template ~63
Delete a tenant notification template. Returns 204 on success, 404 if the template does not exist for this tenant.
| Name | Type | Req | Description |
|---|---|---|---|
| template_id | string | yes | The notification template ID to delete |
| tenant_id | string | yes | The tenant ID that owns the template |
No output schema declared.
No examples provided.
delete_user_list_subscriptions ~30
Delete all list subscriptions for a user.
| Name | Type | Req | Description |
|---|---|---|---|
| user_id | string | yes | The user ID |
No output schema declared.
No examples provided.
delete_user_preference_topic ~53
Delete a user's preference for a specific subscription topic, reverting it to the topic's default status.
| Name | Type | Req | Description |
|---|---|---|---|
| topic_id | string | yes | The subscription topic ID |
| user_id | string | yes | The user ID |
No output schema declared.
No examples provided.
delete_user_token ~41
Delete a specific push token for a user.
| Name | Type | Req | Description |
|---|---|---|---|
| token | string | yes | The token identifier to delete |
| user_id | string | yes | The user ID |
No output schema declared.
No examples provided.
duplicate_broadcast ~35
Copy a broadcast into a new draft. The original is left unchanged.
| Name | Type | Req | Description |
|---|---|---|---|
| broadcast_id | string | yes | The broadcast to copy |
No output schema declared.
No examples provided.
generate_jwt_for_user ~83
Generate a JWT authentication token for a user. Used for client-side SDK auth (Inbox, Preferences, etc.).
| Name | Type | Req | Description |
|---|---|---|---|
| expires_in | string | – | Token expiry duration (e.g. "1h", "2 days") |
| scopes | array | – | Permission scopes for the token |
| user_id | string | yes | The user ID to scope the token to |
No output schema declared.
No examples provided.
get_audience ~32
Get an audience by its ID, including its filter definition.
| Name | Type | Req | Description |
|---|---|---|---|
| audience_id | string | yes | The audience ID |
No output schema declared.
No examples provided.
What is the Courier MCP server?
Courier is an MCP server listed in the public MCP registry as io.github.trycourier/courier. Send notifications, manage templates, and configure integrations with Courier. This page covers its hosted endpoint (https://mcp.courier.com).
Is the Courier MCP server safe to use?
Courier scores 79 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the Courier MCP server expose?
Courier exposes 161 tools: list_messages, get_message, get_message_content, get_message_history, list_notifications, and 156 more. Their descriptions and schemas cost roughly 14,709 tokens of context every time the server is loaded.
Does the Courier MCP server require authentication?
No. We connected to Courier without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.
Is the Courier MCP server still maintained?
Courier is still listed as active in the MCP registry. We last reached this channel on 24 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.