Atlas / MCP servers / iterable / Iterable MCP Server

Iterable MCP ServerCAUTION

mcp/iterable/mcp-server

Iterable MCP Server

Verdict
CAUTION
Grade
C
Trust score
79 /100
Exposed tools
89 53r · 27w · 9d
Transport
stdio
License
MIT
Stars
15
01

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
Read from source at commit eba811680da7OBSERVED · 2026-10-11
02

Connect

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-code
claude mcp add mcp --env ITERABLE_API_KEY=${ITERABLE_API_KEY} -- npx -y @iterable/[email protected]
claude-desktop
{
  "mcpServers": {
    "mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@iterable/[email protected]"
      ],
      "env": {
        "ITERABLE_API_KEY": "${ITERABLE_API_KEY}"
      }
    }
  }
}
03

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.

ToolRiskDescription
abort_campaignreadAbort a campaign that is currently running
activate_triggered_campaignwriteActivate a triggered campaign (requires API triggered campaign activation enabled)
archive_campaignsreadArchive one or more campaigns. Scheduled/recurring campaigns will be cancelled, running campaigns will be aborted.
bulk_delete_catalog_itemsdestructiveBulk delete catalog items by their IDs
bulk_update_subscriptionswriteSubscribe or unsubscribe multiple users to/from a subscription group
bulk_update_userswriteUpdate multiple users at once
cancel_campaignreadCancel a scheduled or recurring campaign
cancel_experimentreadCancel a running or winner_found campaign experiment without declaring a winner.
cancel_export_jobreadCancel a queued or running export job created with
copy_experiment_variantreadCopy a template into a new variant on a draft or ready campaign experiment.
create_blast_campaignwriteCreate a new blast campaign from an existing template. The campaign is created without being scheduled. Use schedule_campaign to schedule it for delivery.
create_catalogwriteCreate a new catalog
create_experimentwriteCreate a draft campaign experiment. The campaign template becomes the control.
create_listwriteCreate a new user list
create_snippetwriteCreate a new snippet with Handlebars templating support
create_triggered_campaignwriteCreate 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_campaignreadDeactivate a triggered campaign (requires API triggered campaign deactivation enabled)
declare_experiment_winnerreadDeclare a winning variant and end a running or winner_found campaign experiment.
delete_catalogdestructiveDelete a catalog
delete_catalog_itemdestructiveDelete a specific catalog item by ID
delete_experimentdestructiveDelete a draft, ready, or errored campaign experiment.
delete_listdestructiveDelete a user list
delete_snippetdestructiveDelete a snippet by ID (numeric) or name (string)
delete_templatesdestructiveDelete one or more templates by ID
delete_user_by_emaildestructiveDelete a user by email address (asynchronous - does not prevent future data collection)
delete_user_by_user_iddestructiveDelete a user by user ID (asynchronous - does not prevent future data collection, deletes all users with same userId)
emailreadEmail address of the user to retrieve
get_available_export_data_typesreadGet 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_campaignreadGet detailed information about a specific campaign
get_campaign_metricsreadGet campaign performance metrics. Requires a date range. Always use the narrowest window possible for performance.
get_campaignsreadRetrieve campaigns
get_catalog_field_mappingsreadGet field mappings and data types for a catalog
get_catalog_itemreadGet a specific catalog item by ID
get_catalog_itemsreadGet items from a catalog with optional pagination and sorting
get_catalogsreadGet list of all catalogs with optional pagination
get_channelswriteGet all available communication channels (email, SMS, push, etc.)
get_child_campaignsreadGet child campaigns generated by a recurring campaign
get_embedded_messagesreadGet embedded messages for a user, grouped by placement ID
get_experimentreadGet detailed information about a specific experiment by ID, including variants summary and constraints
get_experiment_metricsreadGet experiment metrics for A/B testing analysis (currently supports email experiments only)
get_experiment_totalswriteGet 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_trendsreadGet 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_variantsreadGet variant content for an experiment, including subject lines, preheaders, HTML source, and plain text
get_export_filesreadGet 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_jobsreadGet 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_messagesreadGet in-app messages for a user
get_journeysreadGet journeys (workflows) with optional pagination and state filtering
get_list_preview_usersreadPreview users in a list (up to 5000 users)
get_list_sizereadGet the count of users in a specific list
get_list_usersreadGet users in a specific list
get_listsreadRetrieve user lists
get_message_typesreadGet all message types within the project for use in templates
get_sent_messagesreadGet messages sent to a specific user with optional filtering
get_snippetreadGet a snippet by ID (numeric) or name (string)
get_snippetsreadGet all snippets for the current project
get_template_by_client_idreadGet template by client template ID
get_templatesreadRetrieve templates
get_user_by_emailreadGet user profile information by email address
get_user_by_user_idreadGet user profile information by user ID
get_user_events_by_emailreadGet event history for a user by email address
get_user_events_by_user_idreadGet event history for a user by user ID
get_user_fieldsreadGet all user profile field definitions and their types
get_webhooksreadGet all webhooks for the project
list_experimentsreadList experiments with optional filtering by campaign, status, and date range. Supports pagination.
partial_update_catalog_itemwritePartial update (PATCH) a catalog item - updates only specified fields
partial_update_catalog_itemswriteBulk partial update catalog items (up to 1000). Merges document fields per item ID.
replace_catalog_itemwriteReplace (PUT) a catalog item - replaces the entire item with new value
replace_catalog_itemsreadBulk replace catalog items (up to 1000). Each item becomes only the document fields provided.
schedule_campaignwriteSchedule an existing campaign to be sent at a specific time
send_campaignwriteSend an existing scheduled campaign immediately
start_experimentwriteStart a draft or ready campaign experiment.
start_export_jobwriteStart a data export job that processes as a background job. Use
subscribe_to_listreadSubscribe users to a specific list
subscribe_user_by_emailreadSubscribe a user to a subscription group by email
subscribe_user_by_useridreadSubscribe a user to a subscription group by userId
track_bulk_eventsreadTrack multiple events in a single request for better performance
track_eventreadTrack a custom event for a user
trigger_campaignwriteTrigger a campaign to send to specified lists
trigger_journeywriteTrigger a journey (workflow) for a user
unsubscribe_from_listreadUnsubscribe users from a specific list
unsubscribe_user_by_emailreadUnsubscribe a user from a subscription group by email
unsubscribe_user_by_useridreadUnsubscribe a user from a subscription group by userId
update_catalog_field_mappingswriteUpdate catalog field mappings (data types). Valid types: boolean, date, geo_location, long, double, object, and string
update_emailwriteUpdate a user
update_experiment_settingswriteUpdate settings on a draft or ready campaign experiment. Omit a field to leave it unchanged.
update_snippetwriteUpdate a snippet by ID (numeric) or name (string)
update_userwriteUpdate user profile information (accepts email OR userId in params)
update_user_subscriptionswriteUpdate user subscriptions (IMPORTANT: overwrites existing data for any non-null fields specified)
update_webhookwriteUpdate a webhook configuration
04

Trust audit

CAUTIONgrade C · trust 79/100 Install with care. The audit found things worth knowing before you trust its output.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeWARN
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfaceWARN
L4Behavioural (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)

MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
tests/integration/windows-dpapi-live.test.ts:43
const apiKey = "a1b2c3d4e5f6789012345678901234ab";
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
tests/unit/key-manager-dpapi.test.ts:161
apiKey: "legacy-plaintext-key",
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
tests/unit/key-manager-settings.test.ts:20
const apiKey = "abcdefabcdefabcdefabcdefabcdefab";
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
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
Why it matters. 9 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWInventory / provenance · inv.hidden_file · CWE-1104
.nojekyll
.nojekyll
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.prettierignore
.prettierignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.prettierrc.json
.prettierrc.json
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/integration/mcp-protocol.test.ts:41
join(dirname(fileURLToPath(import.meta.url)), "../../package.json"),
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/integration/mcp-protocol.test.ts:55
const { getKeyManager } = await import("../../src/key-manager.js");
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/integration/windows-dpapi-live.test.ts:13
import { KeyManager } from "../../src/key-manager.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/unit/client-detection.test.ts:11
import { detectClientName } from "../../src/client-detection.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/unit/config-resolver.test.ts:3
import { resolveAllowFlags } from "../../src/config";
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
README.md:245
- Allowed: `http://localhost:3000`, `http://127.0.0.1:8080`, `http://[::1]:4000`
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
tests/unit/url-utils.test.ts:18
expect(isHttpsOrLocalhost(new URL("http://127.0.0.1"))).toBe(true);
LOWObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
docs/cursor-install.html:7
<meta http-equiv="refresh" content="0; url=cursor://anysphere.cursor-deeplink/mcp/install?name=iterable&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBpdGVyYWJsZS9tY3Atc2VydmVyIl0sImVudiI6eyJJVEVSQ
LOWObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
docs/cursor-install.html:17
try { window.location.href = 'cursor://anysphere.cursor-deeplink/mcp/install?name=iterable&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBpdGVyYWJsZS9tY3Atc2VydmVyIl0sImVudiI6eyJJVEVSQUJMRV9CQVNFX1
LOWObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
docs/cursor-install.html:24
<a href="cursor://anysphere.cursor-deeplink/mcp/install?name=iterable&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBpdGVyYWJsZS9tY3Atc2VydmVyIl0sImVudiI6eyJJVEVSQUJMRV9CQVNFX1VSTCI6Imh0dHBzOi8vYXB
INFOInventory / provenance · inv.oversize · CWE-1104
images/iterable-mcp-server-setup.gif
images/iterable-mcp-server-setup.gif
Why it matters. 1174568 bytes not read
INFOInventory / provenance · inv.oversize · CWE-1104
images/iterable-mcp-server.png
images/iterable-mcp-server.png
Why it matters. 3262603 bytes not read
INFOPrompt injection · prompt.authority_framing · CWE-94, CWE-1427
README.md:109
**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.

Audited 2026-10-11 · audit v0.4.1 · source sha eba811680da7full audit observations/trust-audit/mcp-server/iterable__mcp-server.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-11eba811680da7CAUTIONC79first audit
06

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.

Advertisement