Iterable MCP ServerCAUTION
Iterable MCP Server
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://www.npmjs.com/package/@iterable/mcp)
Talk to your Iterable data using natural language. Ask questions or give instructions like "How many campaigns did we send last week?", "Show me my most recent templates", or "Build me a beautiful email template that does the following..." and get instant answers without writing code or navigating dashboards.
Supported AI clients:
What is MCP?
Model Context Protocol (MCP) is an open standard that lets AI assistants securely connect to external tools and APIs. This server acts as a bridge between your AI client and Iterable, translating natural language requests into safe API calls.
Installation
Prerequisites:
- Node.js >= 20 (v22 LTS recommended)
- An Iterable API key
npx @iterable/mcp setup
To always use the latest version (auto-update on each restart), add --auto-update:
npx @iterable/mcp setup --auto-update
By default, the setup wizard configures the server in a safe, read‐only mode (no PII tools, no writes, no sends). To selectively enable elevated capabilities during setup, pass --advanced:
# Example: enable advanced setup to configure permissions npx @iterable/mcp setup --advanced
What you'll choose (optional):
- User PII (
ITERABLE_USER_PII): access user profile data, including email addresses, phone numbers, and custom data fields. - Writes (
ITERABLE_ENABLE_WRITES): create, update, and delete resources such as templates, lists, catalogs, campaigns, snippets, and user profiles. - Sends (
ITERABLE_ENABLE_SENDS): send me
eba811680da7OBSERVED · 2026-10-11Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add mcp --env ITERABLE_API_KEY=${ITERABLE_API_KEY} -- npx -y @iterable/[email protected]{
"mcpServers": {
"mcp": {
"command": "npx",
"args": [
"-y",
"@iterable/[email protected]"
],
"env": {
"ITERABLE_API_KEY": "${ITERABLE_API_KEY}"
}
}
}
}Exposed tools (89)
53 read · 27 write · 9 destructive. Blast radius: 9 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
abort_campaign | read | Abort a campaign that is currently running |
activate_triggered_campaign | write | Activate a triggered campaign (requires API triggered campaign activation enabled) |
archive_campaigns | read | Archive one or more campaigns. Scheduled/recurring campaigns will be cancelled, running campaigns will be aborted. |
bulk_delete_catalog_items | destructive | Bulk delete catalog items by their IDs |
bulk_update_subscriptions | write | Subscribe or unsubscribe multiple users to/from a subscription group |
bulk_update_users | write | Update multiple users at once |
cancel_campaign | read | Cancel a scheduled or recurring campaign |
cancel_experiment | read | Cancel a running or winner_found campaign experiment without declaring a winner. |
cancel_export_job | read | Cancel a queued or running export job created with |
copy_experiment_variant | read | Copy a template into a new variant on a draft or ready campaign experiment. |
create_blast_campaign | write | Create a new blast campaign from an existing template. The campaign is created without being scheduled. Use schedule_campaign to schedule it for delivery. |
create_catalog | write | Create a new catalog |
create_experiment | write | Create a draft campaign experiment. The campaign template becomes the control. |
create_list | write | Create a new user list |
create_snippet | write | Create a new snippet with Handlebars templating support |
create_triggered_campaign | write | Create a new triggered campaign from an existing template. The campaign is created in Ready state and must be activated before it can send. |
deactivate_triggered_campaign | read | Deactivate a triggered campaign (requires API triggered campaign deactivation enabled) |
declare_experiment_winner | read | Declare a winning variant and end a running or winner_found campaign experiment. |
delete_catalog | destructive | Delete a catalog |
delete_catalog_item | destructive | Delete a specific catalog item by ID |
delete_experiment | destructive | Delete a draft, ready, or errored campaign experiment. |
delete_list | destructive | Delete a user list |
delete_snippet | destructive | Delete a snippet by ID (numeric) or name (string) |
delete_templates | destructive | Delete one or more templates by ID |
delete_user_by_email | destructive | Delete a user by email address (asynchronous - does not prevent future data collection) |
delete_user_by_user_id | destructive | Delete a user by user ID (asynchronous - does not prevent future data collection, deletes all users with same userId) |
email | read | Email address of the user to retrieve |
get_available_export_data_types | read | Get the list of all available export data types that can be used with start_export_job. Returns an array of data type names that are supported by the Iterable API. |
get_campaign | read | Get detailed information about a specific campaign |
get_campaign_metrics | read | Get campaign performance metrics. Requires a date range. Always use the narrowest window possible for performance. |
get_campaigns | read | Retrieve campaigns |
get_catalog_field_mappings | read | Get field mappings and data types for a catalog |
get_catalog_item | read | Get a specific catalog item by ID |
get_catalog_items | read | Get items from a catalog with optional pagination and sorting |
get_catalogs | read | Get list of all catalogs with optional pagination |
get_channels | write | Get all available communication channels (email, SMS, push, etc.) |
get_child_campaigns | read | Get child campaigns generated by a recurring campaign |
get_embedded_messages | read | Get embedded messages for a user, grouped by placement ID |
get_experiment | read | Get detailed information about a specific experiment by ID, including variants summary and constraints |
get_experiment_metrics | read | Get experiment metrics for A/B testing analysis (currently supports email experiments only) |
get_experiment_totals | write | Get lifetime send and conversion totals for a campaign experiment. Holdout is omitted, missing counts are 0, and lift and confidence are not included. |
get_experiment_trends | read | Get the performance time series for a campaign experiment. Provide both startDateTime and endDateTime, or omit both to use the run window. The span is at most 31 days; a longer default window is clipped to the last 31 days. |
get_experiment_variants | read | Get variant content for an experiment, including subject lines, preheaders, HTML source, and plain text |
get_export_files | read | Get the job status and download URLs for files from a completed export job. Files are added to the list as the export job runs. Use |
get_export_jobs | read | Get a list of recent export jobs for the current project. Jobs can be filtered by state (enqueued, queued, running, completed, failed, cancelled, cancelling). |
get_in_app_messages | read | Get in-app messages for a user |
get_journeys | read | Get journeys (workflows) with optional pagination and state filtering |
get_list_preview_users | read | Preview users in a list (up to 5000 users) |
get_list_size | read | Get the count of users in a specific list |
get_list_users | read | Get users in a specific list |
get_lists | read | Retrieve user lists |
get_message_types | read | Get all message types within the project for use in templates |
get_sent_messages | read | Get messages sent to a specific user with optional filtering |
get_snippet | read | Get a snippet by ID (numeric) or name (string) |
get_snippets | read | Get all snippets for the current project |
get_template_by_client_id | read | Get template by client template ID |
get_templates | read | Retrieve templates |
get_user_by_email | read | Get user profile information by email address |
get_user_by_user_id | read | Get user profile information by user ID |
get_user_events_by_email | read | Get event history for a user by email address |
get_user_events_by_user_id | read | Get event history for a user by user ID |
get_user_fields | read | Get all user profile field definitions and their types |
get_webhooks | read | Get all webhooks for the project |
list_experiments | read | List experiments with optional filtering by campaign, status, and date range. Supports pagination. |
partial_update_catalog_item | write | Partial update (PATCH) a catalog item - updates only specified fields |
partial_update_catalog_items | write | Bulk partial update catalog items (up to 1000). Merges document fields per item ID. |
replace_catalog_item | write | Replace (PUT) a catalog item - replaces the entire item with new value |
replace_catalog_items | read | Bulk replace catalog items (up to 1000). Each item becomes only the document fields provided. |
schedule_campaign | write | Schedule an existing campaign to be sent at a specific time |
send_campaign | write | Send an existing scheduled campaign immediately |
start_experiment | write | Start a draft or ready campaign experiment. |
start_export_job | write | Start a data export job that processes as a background job. Use |
subscribe_to_list | read | Subscribe users to a specific list |
subscribe_user_by_email | read | Subscribe a user to a subscription group by email |
subscribe_user_by_userid | read | Subscribe a user to a subscription group by userId |
track_bulk_events | read | Track multiple events in a single request for better performance |
track_event | read | Track a custom event for a user |
trigger_campaign | write | Trigger a campaign to send to specified lists |
trigger_journey | write | Trigger a journey (workflow) for a user |
unsubscribe_from_list | read | Unsubscribe users from a specific list |
unsubscribe_user_by_email | read | Unsubscribe a user from a subscription group by email |
unsubscribe_user_by_userid | read | Unsubscribe a user from a subscription group by userId |
update_catalog_field_mappings | write | Update catalog field mappings (data types). Valid types: boolean, date, geo_location, long, double, object, and string |
update_email | write | Update a user |
update_experiment_settings | write | Update settings on a draft or ready campaign experiment. Omit a field to leave it unchanged. |
update_snippet | write | Update a snippet by ID (numeric) or name (string) |
update_user | write | Update user profile information (accepts email OR userId in params) |
update_user_subscriptions | write | Update user subscriptions (IMPORTANT: overwrites existing data for any non-null fields specified) |
update_webhook | write | Update a webhook configuration |
Trust audit
CAUTIONgrade C · trust 79/100 Install with care. The audit found things worth knowing before you trust its output.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | WARN |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (1 observation(s))
- Network
- none-observed
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- found
Findings (20)
const apiKey = "a1b2c3d4e5f6789012345678901234ab";
apiKey: "legacy-plaintext-key",
const apiKey = "abcdefabcdefabcdefabcdefabcdefab";
bulk_delete_catalog_items, delete_catalog, delete_catalog_item, delete_experiment, delete_list, delete_snippet, delete_templates, delete_user_by_email, delete_user_by_user_id
.nojekyll
.prettierignore
.prettierrc.json
join(dirname(fileURLToPath(import.meta.url)), "../../package.json"),
const { getKeyManager } = await import("../../src/key-manager.js");import { KeyManager } from "../../src/key-manager.js";import { detectClientName } from "../../src/client-detection.js";import { resolveAllowFlags } from "../../src/config";- Allowed: `http://localhost:3000`, `http://127.0.0.1:8080`, `http://[::1]:4000`
expect(isHttpsOrLocalhost(new URL("http://127.0.0.1"))).toBe(true);<meta http-equiv="refresh" content="0; url=cursor://anysphere.cursor-deeplink/mcp/install?name=iterable&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBpdGVyYWJsZS9tY3Atc2VydmVyIl0sImVudiI6eyJJVEVSQ
try { window.location.href = 'cursor://anysphere.cursor-deeplink/mcp/install?name=iterable&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBpdGVyYWJsZS9tY3Atc2VydmVyIl0sImVudiI6eyJJVEVSQUJMRV9CQVNFX1<a href="cursor://anysphere.cursor-deeplink/mcp/install?name=iterable&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBpdGVyYWJsZS9tY3Atc2VydmVyIl0sImVudiI6eyJJVEVSQUJMRV9CQVNFX1VSTCI6Imh0dHBzOi8vYXB
images/iterable-mcp-server-setup.gif
images/iterable-mcp-server.png
**Permissions:** By default, `keys add` and `keys update` do not prompt for elevated permissions. New keys get secure defaults (PII, writes, and sends disabled); updates keep the key's current permiss
Gates applied: no_behavioural_pass.
eba811680da7full audit observations/trust-audit/mcp-server/iterable__mcp-server.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-11 | eba811680da7 | CAUTION | C | 79 | first audit |
Questions
What is the @iterable/mcp MCP server?
Iterable MCP Server
What tools does @iterable/mcp expose?
89 in total: 53 read-only, 27 that write, and 9 that can delete or overwrite (bulk_delete_catalog_items, delete_catalog, delete_catalog_item, delete_experiment, delete_list). Every one is listed on this page with its risk.
Is @iterable/mcp safe to connect to an agent?
With care. The audit graded it C (79/100) and found 20 things worth knowing before you trust this server, listed below with the exact line each was found on. Separately from the audit: 9 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does @iterable/mcp need?
It reads ITERABLE_API_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does @iterable/mcp run?
It speaks stdio, so it runs as a local process your client starts. It is published on npm as @iterable/mcp at 1.9.0.
How current is this page?
The grade is for one exact copy of the source (eba811680da7), read on 2026-10-11. The repository is watched and re-audited when it changes.